Literal decimal floating-point numbers cannot always be represented precisely using the double
primitive type because the underlying representation of double
is binary. This imprecision becomes apparent when a BigDecimal
is constructed from a double
.
Consequently, the BigDecimal(double val)
constructor must not be invoked with floating-point literals.
Noncompliant Code Example
This noncompliant code example passes a double
value to the BigDecimal
constructor. Because the decimal literal 0.1
cannot be precisely represented by a double
, precision of the BigDecimal
is affected.
// prints 0.1000000000000000055511151231257827021181583404541015625 System.out.println(new BigDecimal(0.1));
Compliant Solution
This compliant solution passes the decimal literal as a String
so that the BigDecimal(String val)
constructor is invoked, and precision is preserved.
// prints 0.1 System.out.println(new BigDecimal("0.1"));
Risk Assessment
Using the BigDecimal(double val)
constructor with decimal floating-point literals can lead to loss of precision.
Rule |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
---|---|---|---|---|---|
NUM10-J |
low |
probable |
low |
P6 |
L2 |
Automated Detection
Automated detection appears to be straightforward.
Bibliography
[JLS 2005] |
03. Numeric Types and Operations (NUM) NUM11-J. Do not rely on the default string representation of floating-point values