In the code, I have
int a = 62;
int b = 132;
double c;
c = (double) a/b;
System.out.println(c);
which prints out the value of c as 0.469696968793869
How can I just keep a short format for c, like 0.4697
DecimalFormat df = new DecimalFormat("#.####");
System.out.print(df.format(c));
#.#### to keep four decimal places but trailing zeros would be ignored. If you want to four decimal places including any trailing zeros, use format string #.0000 instead.
What you want is NumberFormat.
NumberFormat formatter = new DecimalFormat("0.0000");
String s = formatter.format(c);
System.out.println(s);
(The 0 symbol shows a digit or 0 if no digit present.)
See this page for more information.
Use:
System.out.format("%.4f%n", c);
Or:
DecimalFormat myFormatter = new DecimalFormat(".####");
String output = myFormatter.format(c);
System.out.println(output);
See this Java tutorial for more details.
System.out.printf("%.4f%n", c);
The correct way to keep (not print) a result of prescribed precision is to use the java.math.BigDecimal class as follows.
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
public class Foo {
private static final int PRECISION = 5;
private static final MathContext MATH_CONTEXT = new MathContext(PRECISION, RoundingMode.HALF_UP);
public static void main(String... args) {
double a = 62;
double b = 132; // Doubles used to avoid integer division truncation
final BigDecimal c = new BigDecimal(a / b, MATH_CONTEXT);
System.out.println(c); // Prints 0.46970
}
}
Related
This is probably a really simple question but, is there a simple way to go from
Double myLongNumber = 50.12345678998658576546
to
Double myLongNumber = 50.1234
?
I just want to reduce the number of decimal digits, not remove them all.
If you really want to change that number, you can do something like
Double myNotSoLongNumber = Math.round(myLongNumber * 1E4) / 1E4;
If you want to display a Double with less fraction digits, use
String myLongNumberAsString = String.format("%.4f", myLongNumber);
Please check below options
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Locale;
import org.apache.commons.math3.util.Precision;
class DoubleTrimmer {
public static void main(String[] args) {
Double myLongNumber = 50.12345678998658576546;
//Option1. just trim the number
Double trimmedNumber = Double.valueOf(String.format(Locale.ENGLISH, "%.4f", myLongNumber));
System.out.println(trimmedNumber);
//Option2. Round the number using BigDecimal
trimmedNumber = round(myLongNumber, 4);
System.out.println(trimmedNumber);
//Option3. Round the number using Apache commons math
trimmedNumber = Precision.round(myLongNumber, 4);
System.out.println(trimmedNumber);
}
public static double round(double value, int places) {
if (places < 0) throw new IllegalArgumentException();
BigDecimal bd = BigDecimal.valueOf(value);
bd = bd.setScale(places, RoundingMode.HALF_UP);
return bd.doubleValue();
}
}
Use BigDecimal package
import java.math.BigDecimal;
public class ReduceDecimalNumbers {
public static void main(String args[]){
double myLongNumber = 50.12345678998658576546;
int decimalsToConsider = 4;
BigDecimal bigDecimal = new BigDecimal(myLongNumber );
bigDecimal = new BigDecimal(myLongNumber );
BigDecimal roundedValueWithDivideLogic = bigDecimal.divide(BigDecimal.ONE,decimalsToConsider,BigDecimal.ROUND_HALF_UP);
System.out.println("Rounded value with Dividing by one = "+roundedValueWithDivideLogic);
}
}
output:
Rounded value with Dividing by one = 50.1235
or you can try this
public class round{
public static void main(String args[]){
double myLongNumber = 50.12345678998658576546;
double roundOff = Math.round(myLongNumber *1E4)/1E4;
System.out.println(String.format("%.4f", roundOff)); //%.4f defines decimal precision you want
}
}
output:
50.1235
Below is the double return type function and i would like to get the answer with precision of 2 zeros. My current answer is coming out to be -4.5. Whereas i want it to be -4.50. Any kind of help will be really appreciated
public double getAmount(){
double ftotal = car.hello();
return Math.round(ftotal * 100)/100.0d;
}
The returned value is a Double so you can't pad 0s to a Double.
So you must format the returned value to create a string, like:
NumberFormat formatter = new DecimalFormat("#0.00");
String number = formatter.format(getTotal());
System.out.println(number);
Refer below code -
import java.text.DecimalFormat;
public class Decimal2{
private static DecimalFormat df2 = new DecimalFormat(".##");
public static void main(String[] args) {
double input = 62.123454;
System.out.println("double : " + df2.format(input));
}
}
I have a method that is converting a decimal (double value) into a fraction and putting the numerator and denominator values into an int[] of size 2.
Testing it works out fine for most values except when I hit 0.0001. Then the return value is 1.0/1.0.
The method:
private static int[] toFractionPos(double x){
String[] parts = Double.toString(x).split("\\.");
double den = Math.pow(10, parts[1].length()); //denominator
double num = Double.parseDouble(parts[0]) * den + Double.parseDouble(parts[1]); //numerator
return reduceFraction((int)num, (int)den);
}
reduceFraction() method:
public static int[] reduceFraction(int num, int den){
int gcf = GCF(num, den); //greatest common factor
int[] rf = {num/gcf, den/gcf};
return rf;
}
Thanks!
The algorithm seems fine. However, using double is not suitable for this kind of problem, because precision decreases as the scale grows.
You should use BigDecimal and BigInteger instead. I've roughly modified your example so that it works with them, but I haven't taken care of details, i.e. parsing the String shouldn't be necessary since scale can be retrieved from a BigDecimal with a getter, you can configure different rounding modes, etc:
import java.math.BigDecimal;
import java.math.BigInteger;
public class Sample {
static int[] toFractionPos(BigDecimal x) {
String[] parts = x.toString().split("\\.");
BigDecimal den = BigDecimal.TEN.pow(parts[1].length()); // denominator
BigDecimal num = (new BigDecimal(parts[0]).multiply(den)).add(new BigDecimal(parts[1])); // numerator
return reduceFraction(num.intValue(), den.intValue());
}
static int[] reduceFraction(int num, int den) {
int gcd = BigInteger.valueOf(num).gcd(BigInteger.valueOf(den)).intValue(); // greatest
// common
// divisor
int[] rf = { num / gcd, den / gcd };
return rf;
}
public static void main(String[] args) {
int[] fraction = toFractionPos(new BigDecimal("0.0001"));
System.out.println(fraction[0] + "/" + fraction[1]); // 1/10000
}
}
Note: optimizations left as an excercise ;)
You shouldn't work with doubles as you are losing precision and this can lead to serious errors. But in the case of 1.0001 the problem is that:
Double.toString(1.0001) == "1.0E-4"
Then you try to parse "0E-4" and you get 0 instead of 1. You could do the following if you expect at most 10 decimal points:
DecimalFormat df = new DecimalFormat("0",
DecimalFormatSymbols.getInstance(Locale.ENGLISH));
df.setMaximumFractionDigits(10);
String[] parts = df.format(x).split("\\.");
How about this?
private static int[] toFractionPos(double x){
int den = (int)Math.pow(10,(int)Math.log10(Integer.MAX_VALUE));
int num = (int)(x*den);
return reduceFraction(num, den);//this came from your code
}
I think this will work,
public int[] Fraction(double n) {
BigDecimal p = BigDecimal.ONE;
BigDecimal dn = BigDecimal.valueOf(n);
while(true){
dn = dn.multiply(p);
if( dn.compareTo(new BigDecimal(dn.toBigInteger()))==0 )
break;
else
p = p.multiply(BigDecimal.TEN);
}
BigInteger num=dn.toBigInteger(), den=p.toBigInteger(), g=num.gcd(den);
num = num.divide(g);
den = den.divide(g);
int[] res = new int[2];
res[0] = num.intValue();
res[0] = den.intValue();
return res;
}
999 to 999
1000 to 1k
1500000 to 1.5m
and so on, I would like to not lose any precision at all
Also, need to convert them back to their original value
1.5m to 1500000
etc
The highest it would go is 11 digits max
Thanks
How about this:
import static java.lang.Double.parseDouble;
import static java.util.regex.Pattern.compile;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
...
private static final Pattern REGEX = compile("(\\d+(?:\\.\\d+)?)([KMG]?)");
private static final String[] KMG = new String[] {"", "K", "M", "G"};
static String formatDbl(double d) {
int i = 0;
while (d >= 1000) { i++; d /= 1000; }
return d + KMG[i];
}
static double parseDbl(String s) {
final Matcher m = REGEX.matcher(s);
if (!m.matches()) throw new RuntimeException("Invalid number format " + s);
int i = 0;
long scale = 1;
while (!m.group(2).equals(KMG[i])) { i++; scale *= 1000; }
return parseDouble(m.group(1)) * scale;
}
If they weren't final you could extend java.lang.Integer etc. to override the toString() method. Is it worth creating a java.lang.Number subclass? Probably not. You could create your own classes: MyInteger, MyFloat etc using composition (they'll have an attribute to hold the numeric value) and override the toString() method to return the formats you want.
For the other way around, you could create factory methods in your MyXXX classes that creates objects containing the numeric value of the string (such as "1m").
The good thing is that kind of work lends itself well for unit testing.
You could probably obtain what you want by using directly a NumberFormat subclass but depending on how you're going to use it, the above design could be better.
static String[] prefixes = {"k","M","G"};
// Formats a double to a String with SI units
public static String format(double d) {
String result = String.valueOf(d);
// Get the prefix to use
int prefixIndex = (int) (Math.log10(d) / Math.log10(10)) / 3;
// We only have a limited number of prefixes
if (prefixIndex > prefixes.length)
prefixIndex = prefixes.length;
// Divide the input to the appropriate prefix and add the prefix character on the end
if (prefixIndex > 0)
result = String.valueOf(d / Math.pow(10,prefixIndex*3)) + prefixes[prefixIndex-1];
// Return result
return result;
}
// Parses a String formatted with SI units to a double
public static double parse(String s) {
// Retrieve the double part of the String (will throw an exception if not a double)
double result = Double.parseDouble(s.substring(0,s.length()-1));
// Retrieve the prefix index used
int prefixIndex = Arrays.asList(prefixes).indexOf(s.substring(s.length()-1)) + 1;
// Multiply the input to the appropriate prefix used
if (prefixIndex > 0)
result = result * Math.pow(10,prefixIndex*3);
return result;
}
should be an easy one. I originally was gonna do this in javascript but have to do it prior to setting to the form in my handler page. Anyway I need to make these values have 2 decimal places. Ex 219333.5888888 needs to be 219333.58. Is there a trim function or something?
form.setUnitRepairCost(Double.toString(jobPlanBean.getUnitTotalCost())); //UNIT REPAIR COST
form.setUnitMaterialCost(Double.toString(jobPlanBean.getUnitTotalMaterialCost())); //UNIT MATERIAL COST
here is the simple example to format the decimal value
import java.text.*;
public class DecimalPlaces {
public static void main(String[] args) {
double d = 1.234567;
DecimalFormat df = new DecimalFormat("#.##");
System.out.print(df.format(d));
}
}
multiply the double by 100.0 and cast this to an int then take that int and cast it to a double and divide by 100.0
int temp = (int)(longDouble*100.0);
double shortDouble = ((double)temp)/100.0;
public static void main(String[] args) {
double d = 6.3546;
DecimalFormat df = new DecimalFormat("#.##");
System.out.print(df.format(d));
}
For getting a double back and not a string:
double d = 80.123;
DecimalFormat df = new DecimalFormat("#.##");
double p = Double.parseDouble(df.format(d));
How about:
new java.text.DecimalFormat("0.00").format( yourNumber );
Here is String manipulation to truncate double value up to tow decimal places.
public static String truncateUptoTwoDecimal(double doubleValue) {
String value = String.valueOf(doubleValue);
if (value != null) {
String result = value;
int decimalIndex = result.indexOf(".");
if (decimalIndex != -1) {
String decimalString = result.substring(decimalIndex + 1);
if (decimalString.length() > 2) {
result = value.substring(0, decimalIndex + 3);
} else if (decimalString.length() == 1) {
result = String.format(Locale.ENGLISH, "%.2f",
Double.parseDouble(value));
}
}
return result;
}
return null;
}
As suggested by other you can use class DecimalFormat of java.text.DecimalFormat. We can also use DecimalFormat to round off decimal values.
Example:
import java.math.RoundingMode;
import java.text.DecimalFormat;
public class DecimalDemo {
private static DecimalFormat decimalFormatter = new DecimalFormat("#.##");
public static void main(String[] args) {
double number = 2.14159265359;
System.out.println("Original Number : " + number);
System.out.println("Upto 2 decimal : " + decimalFormatter.format(number)); //2.14
// DecimalFormat, default is RoundingMode.HALF_EVEN
decimalFormatter.setRoundingMode(RoundingMode.DOWN);
System.out.println("Down : " + decimalFormatter.format(number)); //2.14
decimalFormatter.setRoundingMode(RoundingMode.UP);
System.out.println("Up : " + decimalFormatter.format(number)); //2.15
}
}
Look into using a Decimal Format :
DecimalFormat twoDForm = new DecimalFormat("#.##");
By using those two methods you can handle all the exceptions also :
private String convertedBalance(String balance){
String convertedBalance = balance.toString();
Double d;
try {`enter code here`
d = Double.parseDouble(balance.toString());
Log.i("ConvertedNumber", "d (amount) = "+d.toString());
d = round(d, 2);
DecimalFormat f = new DecimalFormat("0.00");
convertedBalance = f.format(d);
Log.i("ConvertedNumber", "convertedBalance = "+convertedBalance);
}catch (NumberFormatException e){
Log.i("ConvertedNumber", "Number format exception");
}
return convertedBalance;
}
public static double round(double value, int places) {
if (places < 0) throw new IllegalArgumentException();
BigDecimal bd = new BigDecimal(value);
bd = bd.setScale(places, RoundingMode.HALF_UP);
return bd.doubleValue();
}
Yes, DecimalFormat: http://www.exampledepot.com/egs/java.text/FormatNum.html
DecimalFormat Class
public static double truncateDecimals(double d, int len) {
long p = pow(10, len);
long l = (long)(d * p);
return (double)l / (double)p;
}
public static long pow(long a, int b) {
long result = 1;
for (int i = 1; i <= b; i++) {
result *= a;
}
return result;
}
You can simply use String.format() as below.
double height = 175.8653;
System.out.println("Height is: " + String.format("%.2f", height));
This will trim the double value to two decimal places.