The problem is that for float and double you use 32 and 64 bits, respectively, to represent both the integer and decimal parts of the number. The problem arises when you try to represent a fractional value that does not actually have an exact decimal representation in binary bits.
Take .1, for example, there is no way to accurately represent this in base 2, more than there is a way to accurately represent 1/3 in base 10.
So java uses some tricks so that when you say:
float f = 3.1; System.out.println(f);
He prints the correct number. However, when you start doing arithmetic with these values, you get rounding errors.
BigDecimal is accurate because it uses a different view. It internally stores BigInteger (which uses int [] to represent huge numbers). He then uses the precision value to tell how many of these integer digits are after the decimal point.
For example, the value 3.1 will be represented in BigDecimal as 31, precision = 1 For this reason, BigDecimal does not suffer from the same rounding issues as float and double.
However, when you use the float / double value to initialize a BigDecimal, the same rounding error does this in the BigDecimal instance. To do this, it is recommended to use String to construct the value.
source share