Working with string representations of floating point values can produce incorrect conclusions about the precision of the values. For example, consider the conversion of a value from type float
to type double
, a widening primitive conversion. Refer to the guideline NUM10-J. Beware of precision loss when converting primitive integers to floating-point for more details about such conversions.
String representations of floating-point numbers shall not be compared or inspected. When the value of a 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]]
NUM08-J. Do not construct BigDecimal objects from floating-point literals 03. Floating Point (FLP) 04. Object Orientation (OBJ)