Why is this an issue?
The BigDecimal
is used to represents immutable, arbitrary-precision signed decimal numbers.
Differently from the BigDecimal
, the double
primitive type and the Double
type have limited precision due to
the use of double-precision 64-bit IEEE 754 floating point. Because of floating point imprecision, the BigDecimal(double)
constructor can
be somewhat unpredictable.
For example writing new BigDecimal(0.1)
doesn’t create a BigDecimal which is exactly equal to 0.1, but it is equal to
0.1000000000000000055511151231257827021181583404541015625. This is because 0.1 cannot be represented exactly as a double (or, for that matter, as a
binary fraction of any finite length).
How to fix it
Use BigDecimal.valueOf
, which uses a string under the covers to eliminate floating point rounding errors, or the constructor that
takes a String
argument.
Code examples
Noncompliant code example
double d = 1.1;
BigDecimal bd1 = new BigDecimal(d); // Noncompliant
BigDecimal bd2 = new BigDecimal(1.1); // Noncompliant
Compliant solution
double d = 1.1;
BigDecimal bd1 = BigDecimal.valueOf(d); // Compliant
BigDecimal bd2 = new BigDecimal("1.1"); // Compliant
Resources
Documentation