String representations of floating point values can lead to incorrect conclusions about the precision of the values. For example, consider converting a value of type float
to the type double
, a widening primitive conversion. Refer to the guideline FLP10-J. Do not cast primitive integer types to floating-point types without range checks for more details about such conversions. When the value of the float
variable must be represented exactly using the double
type, an explicit assignment is more appropriate than first converting the floating point value to a String
and then to a double
.
Noncompliant Code Example (String Comparison)
This noncompliant code example attempts a string-based comparison of a floating-point number.
int i = 1; String s = Double.valueOf(i / 1000.0).toString(); if (s.equals("0.001")) { // ... }
However s
actually contain the string "0.0010"
. Consequently, the comparison unexpectedly fails.
Noncompliant Code Example (Regex)
This noncompliant code example attempts to mitigate the extra trailing zero by using a regular expression on the string before comparing it.
int i = 1; String s = Double.valueOf(i / 1000.0).toString(); s = s.replaceFirst("[.0]*$", ""); if (s.equals("0.001")) { // ... }
Thie comparison does succeed on this code.
However, the comparison fails on this similar code, which uses 1/10000.0
instead of 1/1000.0
. The string produced is not 0.00010
but rather 1.0E-4
.
int i = 1; String s = Double.valueOf(i / 10000.0).toString(); s = s.replaceFirst("[.0]*$", ""); if (s.equals("0.0001")) { // ... }
Compliant Solution (String Comparison)
This compliant solution uses the BigDecimal
class to avoid precision loss. It then performs a numeric comparison, which passes as expected.
int i = 1; BigDecimal d = new BigDecimal(Double.valueOf(i / 1000.0).toString()) if (d.compareTo(new BigDecimal("0.001")) == 0) { // ... }
Risk Assessment
Relying on the string representation of floating point types can result in imprecise values.
Guideline |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
---|---|---|---|---|---|
FLP09-J |
low |
likely |
medium |
P6 |
L2 |
Automated Detection
TODO
Related Vulnerabilities
Bibliography
[[API 2006]]
[[JLS 2005]]
FLP08-J. Avoid using floating point literals with the BigDecimal constructor Floating Point (FLP) Object Orientation (OBJ)