As @Benoit already said in a comment, to keep the full precision of your number, you need a BigDecimal:
BigDecimal hashValue = new BigDecimal("20790123833965.960938");
DecimalFormat formatter = new DecimalFormat("#0.000000");
System.out.println(formatter.format(hashValue));
Output:
Answer from Anonymous on Stack Overflow20790123833965.960938
As @Benoit already said in a comment, to keep the full precision of your number, you need a BigDecimal:
BigDecimal hashValue = new BigDecimal("20790123833965.960938");
DecimalFormat formatter = new DecimalFormat("#0.000000");
System.out.println(formatter.format(hashValue));
Output:
20790123833965.960938
Use this code, it will work.
public class JavaFormatter {
public static void main(String args[]) {
BigDecimal hashValue = new BigDecimal("20790123833965.960938");
DecimalFormat formatter = new DecimalFormat("#.######");
System.out.println(formatter.format(hashValue));
}
}
Use setRoundingMode, set the RoundingMode explicitly to handle your issue with the half-even round, then use the format pattern for your required output.
Example:
DecimalFormat df = new DecimalFormat("#.####");
df.setRoundingMode(RoundingMode.CEILING);
for (Number n : Arrays.asList(12, 123.12345, 0.23, 0.1, 2341234.212431324)) {
Double d = n.doubleValue();
System.out.println(df.format(d));
}
gives the output:
12
123.1235
0.23
0.1
2341234.2125
EDIT: The original answer does not address the accuracy of the double values. That is fine if you don't care much whether it rounds up or down. But if you want accurate rounding, then you need to take the expected accuracy of the values into account. Floating point values have a binary representation internally. That means that a value like 2.7735 does not actually have that exact value internally. It can be slightly larger or slightly smaller. If the internal value is slightly smaller, then it will not round up to 2.7740. To remedy that situation, you need to be aware of the accuracy of the values that you are working with, and add or subtract that value before rounding. For example, when you know that your values are accurate up to 6 digits, then to round half-way values up, add that accuracy to the value:
Double d = n.doubleValue() + 1e-6;
To round down, subtract the accuracy.
Assuming value is a double, you can do:
(double)Math.round(value * 100000d) / 100000d
That's for 5 digits precision. The number of zeros indicate the number of decimals.
I'm not sure I fully understand your question so let me recap:
- You have some
doublevalue with potentially more than 6 significant fraction digits. - You want to round that value to 6 fraction digits and use the HALF_UP mode.
- You want to display only the first 2 fraction digits (I don't understand why but I won't question it).
In that case I'd suggest you first use BigDecimal for the rounding since otherwise you could get precision errors:
double value = 1.23456789;
BigDecimal rounded = BigDecimal.valueOf( value ).setScale(6, RoundingMode.HALF_UP);
That should result in the value 1.234568.
Then use NumberFormat like you did but always round down:
DecimalFormat df = (DecimalFormat)DecimalFormat.getInstance(Locale.US);
df.applyPattern("#.##");
df.setRoundingMode(RoundingMode.DOWN);
String output = df.format( rounded );
That should result in 1.23.
With your input value of 4.23499999999235 you'd then get 4.235000 (rounded to 6 digits) and 4.23.
Edit: I'm not aware of any rounding mode that rounds 4.23499999999235 to 4.24 but you should be able to achieve it by chaining multiple setScale() calls:
BigDecimal rounded = BigDecimal.valueOf( value );
for( int digit = 6; digit >= 2; digit--) {
rounded = rounded .setScale( digit, RoundingMode.HALF_UP );
}
That should apply rounding to fraction digit 6, then 5 etc. and finally round to 4.24. I'm still not sure that's the right way to round but you know your requirements better than me :)
Considering you are outputting this to a string, why not use
String output = String.format(java.util.Locale.US,"%.2f", doubleValue);
instead of all of the DecimalFormat stuff? This will leave doubleValue as the original value, keeping the precision.
By default, printf shows 6 decimal digits
You can control the number of decimal digits to show by explicitly specifying the precision. For example, for 12 decimal digits you can do:
printf("%.12f", val);
API reference: http://docs.oracle.com/javase/8/docs/api/java/util/Formatter.html#dndec
If you want to get equivalent output to System.out.println but for some reason want to keep using printf, then you can do the following:
System.out.printf("%d\t\t%f\n", (x + 1), Double.toString(startingOrganisms));
This is due to the fact that by default for double or float printf print number upto 6 decimal places. You need to specify the precision if you want to control how many decimal places you want to print via printf. System.out.println prints exact value of double/float without adding some default decimal points.
e.g.
double d = 1.0;
// it will print 1.000000
System.out.printf("%f\n", d);
//1.0
System.out.printf("%.1f", d);
//1.0
System.out.println(d);
Use a DecimalFormatter:
double number = 0.9999999999999;
DecimalFormat numberFormat = new DecimalFormat("#.00");
System.out.println(numberFormat.format(number));
Will give you "0.99". You can add or subtract 0 on the right side to get more or less decimals.
Or use '#' on the right to make the additional digits optional, as in with #.## (0.30) would drop the trailing 0 to become (0.3).
If you want to print/write double value at console then use System.out.printf() or System.out.format() methods.
System.out.printf("\n$%10.2f",shippingCost);
System.out.printf("%n$%.2f",shippingCost);
You can try BigDecimal for this purpose
Double toBeTruncated = new Double("3.5789055");
Double truncatedDouble = BigDecimal.valueOf(toBeTruncated)
.setScale(3, RoundingMode.HALF_UP)
.doubleValue();
You can't set the precision of a double (or Double) to a specified number of decimal digits, because floating-point values don't have decimal digits. They have binary digits.
You will have to convert into a decimal radix, either via BigDecimal or DecimalFormat, depending on what you want to do with the value later.
See also my answer to this question for a refutation of the inevitable *100/100 answers.