`BigDecimal` constructed from `double` may be impreciseJAVA-W0008
BigDecimals constructed from a double may not be represented correctly.
This code creates a BigDecimal from a double value that may not translate well to a decimal number. This happens due to the way real numbers are represented in binary. Only rational numbers that are powers of 2 can be represented with perfect accuracy in types such as float and double. For example, numbers such as 1/16 or 1/1024 are precisely representable whereas the binary representation of a number such as 1/10 would expand infinitely (similarly to how 1/3's decimal form expands infinitely when you try writing it down).
From BigDecimal's JavaDocs:
One might assume that writing
new BigDecimal(0.1)in Java creates aBigDecimalwhich is exactly equal to0.1(an unscaled value of 1, with a scale of 1), but it is actually equal to0.1000000000000000055511151231257827021181583404541015625.
For more information on why this occurs, see this wikipedia article
You probably want to use the BigDecimal.valueOf(double d) method, which uses the String representation of the double to create the BigDecimal (e.g., BigDecimal.valueOf(0.1) gives 0.1).
BigDecimal bad = new BigDecimal(0.1);
BigDecimal good = BigDecimal.valueOf(0.1);
References
- CERT NUM10-J - Do not construct BigDecimal objects from floating-point literals
- Spotbugs - DMI_BIGDECIMAL_CONSTRUCTED_FROM_DOUBLE