Literal decimal floating-point numbers cannot always be precisely represented as an IEEE 754 floating-point value. Consequently, the BigDecimal(double val)
constructor must not be passed a floating-point literal as an argument when doing so results in an unacceptable loss of precision.
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 // when run in FP-strict mode 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 the precision is preserved:
// Prints 0.1 // when run in FP-strict mode 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 is straightforward.
Tool | Version | Checker | Description |
---|---|---|---|
Parasoft Jtest | 9.5 | PB.NUM.BBDCC | Implemented |
SonarQube Java Plugin | Unable to render {include} The included page could not be found. | S2111 |
Bibliography
[JLS 2015] | |
[Seacord 2015] | NUM10-J. Do not construct BigDecimal objects from floating-point literals LiveLesson |