Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

BigDecimal from Double incorrect value?

I am trying to make a BigDecimal from a string. Don't ask me why, I just need it! This is my code:

Double theDouble = new Double(".3");
System.out.println("The Double: " + theDouble.toString());
BigDecimal theBigDecimal = new BigDecimal(theDouble);
System.out.println("The Big: " + theBigDecimal.toString());

This is the output I get?

The Double: 0.3
The Big: 0.299999999999999988897769753748434595763683319091796875

Any ideas?

like image 820
Diego Avatar asked Sep 11 '10 23:09

Diego


People also ask

Is BigDecimal more precise than double?

double has 8 bytes to represent the value, its precision is limited to 15 decimal digits, see http://en.wikipedia.org/wiki/IEEE_754-1985. BigDecimal precision is de facto unlimited since it is based on an int array of arbitrary length.

Why use BigDecimal instead of double?

BigDecimal reduces the chances of calculation errors. On double numbers, the BigDecimal class provides arithmetic, scale management, rounding, comparison, format conversion, and hashing functions. It compensates for the time complexity by handling large and small floating-point integers with exceptional precision.

How much slower is BigDecimal than double?

But now I have some code where performance is an issue, and BigDecimal is more than 1000 times (!) slower than double primitives. The calculations are very simple: what the system does is calculating a = (1/b) * c many many times (where a , b and c are fixed-point values).

What is BigDecimal setScale?

BigDecimal. setScale(int newScale, int roundingMode) Returns a BigDecimal whose scale is the specified value, and whose unscaled value is determined by multiplying or dividing this BigDecimal 's unscaled value by the appropriate power of ten to maintain its overall value.


1 Answers

When you create a double, the value 0.3 cannot be represented exactly. You can create a BigDecimal from a string without the intermediate double, as in

new BigDecimal("0.3")

A floating point number is represented as a binary fraction and an exponent. Therefore there are some number that cannot be represented exactly. There is an analogous problem in base 10 with numbers like 1/3, which is 0.333333333..... Any decimal representation of 1/3 is inexact. This happens to a DIFFERENT set of fractions in binary, and 0.3 is one of the set that is inexact in binary.

like image 180
Jim Garrison Avatar answered Nov 15 '22 14:11

Jim Garrison