Decimal Literal decimal floating-point numbers cannot always be precisely represented as a BigDecimal
when the BigDecimal(double val)
constructor is used. The primitive type double
cannot precisely represent all decimal fractions because its underlying representation is binaryan IEEE 754 floating-point value. Consequently, the input to the BigDecimal(double val)
constructor can lose precision before the constructor is ever invokedmust 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 of thisthe decimal literal 0.1
cannot be precisely represented by a double
, precision of the literal BigDecimal
is affected.
Code Block | ||
---|---|---|
| ||
// printsPrints 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:
Code Block | ||
---|---|---|
| ||
// printsPrints 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 leads 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 is straightforward.
Related Vulnerabilities
...
Tool | Version | Checker | Description | ||||||
---|---|---|---|---|---|---|---|---|---|
Parasoft Jtest |
| CERT.NUM10.BBDCC | Do not pass floating point values to the 'BigDecimal' constructor | ||||||
PVS-Studio |
| V6068 | |||||||
SonarQube |
| S2111 | "BigDecimal(double)" should not be used |
Bibliography
[JLS |
...
...
...
use floating point variables as loop counters 07. Floating Point (FLP) FLP09-J. Do not rely on the default string representation of floating point values