Reputation: 2983
I'm trying to convert some string values in number using DecimalFormat. I try to explain you my problem in a better way:
I have the following method:
private BigDecimal loadBigDecimal(String value){
BigDecimal bigDecimalToReturn = null;
DecimalFormat df = new DecimalFormat("##.###");
bigDecimalToReturn = new BigDecimal(df.parse(value).doubleValue());
return bigDecimalToReturn;
}
Now if I try to run the method:
BigDeciaml dec = myObject.loadBigDecimal("120,11");
The value of dec is 120.1099999999999994315658113919198513031005859375
.
Why decimalFormat is changing the scale of my value?
Upvotes: 1
Views: 687
Reputation: 8359
That is because of the df.parse(value).doubleValue()
call. At this point, the value is converted to a double.
double represent plus or minus the sum of powers of 2 (with positive and negative exponents).
One can write 120 as 64+32+16+8.
But one can't write 0.11 as a finite sum of power of 2.
So there is an approximation.
0.1099999999999994315658113919198513031005859375
Which is a sum of power of 2.
It's look like BigDecimal as a constructor with a string for parameter. Maybe you can just use it.
BigDecimal dec = new BigDecimal("120,11");
Upvotes: 1
Reputation: 12316
You are doing conversion to double and backwards. That's unnecessary and introduces rounding errors. You should use the following code:
private BigDecimal loadBigDecimal(String value) throws ParseException {
DecimalFormat df = new DecimalFormat("##.###");
df.setParseBigDecimal(true);
return (BigDecimal) df.parse(value);
}
Upvotes: 5
Reputation: 9776
Doubles are only approximations. That is correct for a double. If you want a specific scale, you need to tell it in the BigDecimal constructor.
Upvotes: 3