I am formatting a decimal number and I have the following criteria to format it:
- Number should be at most two decimal places (10.1234=>10.12)
- If there is only one digit after decimal then it will ends up with an extra 0 (10.5=>10.50)
- Thousand separator will be comma (12345.2345 => 12,345.23)
I have written following logic:
double x = Double.parseDouble(value.toString());
String dec = x % 1 == 0 ? new java.text.DecimalFormat("###,###.##").format(x) : new java.text.DecimalFormat("###,###.00").format(x);
Now it is printing:
11111111111110.567=>11,111,111,111,110.57
111111111111110.567=>111,111,111,111,110.56
1111111111111110.567=>1,111,111,111,111,110.60
11111111111111110.567=>11,111,111,111,111,110
111111111111111110.567=>111,111,111,111,111,104
1111111111111111110.567=>1,111,111,111,111,111,170
I don't understand why the behavior changes. How should I print 1111111111111111110.567
as 1,111,111,111,111,111,110.57
?
The problem is that you can't represent 1111111111111111110.567 exactly as a double
in the first place. (You can't even represent your shortest value exactly, but the inaccuracy will increase significantly as you increase the magnitude.)
A double
only has about 17 significant digits of useful data anyway - you're trying to get 22 digits.
Use BigDecimal
if you want more precision - but be aware that this will change other things too. What kind of value are you trying to represent, anyway? Natural values (weights, distances etc) are appropriate for double
; artificial values (particularly currency values) are appropriate for BigDecimal
.
I managed to get this (You have to use BigDecimal
):
import java.math.BigDecimal;
import java.text.NumberFormat;
public class Sandbox {
public static void main(String[] args) {
BigDecimal x = new BigDecimal("1111111111111111110.567");
DecimalFormat formatter = new DecimalFormat("###,###.00");
System.out.println(formatter.format(x));
}
}
OUTPUT:
1,111,111,111,111,111,110.57
Resource Links: DecimalFormat
and BigDecimal
One more thing, you have to enter the BigDecimal number as a String
or else it will cause problems.
BigDecimal x = new BigDecimal(1111111111111111110.567) will output the following.
1,111,111,111,111,111,168.00