String representations of floating-point numbers must not be compared or inspected.
Noncompliant Code Example (String Comparison)
This noncompliant code example compares the string representations of two floating-point values.
int i = 1; String s = Double.valueOf(i / 1000.0).toString(); if (s.equals("0.001")) { // ... }
The comparison unexpectedly fails because s
contains the string "0.0010"
.
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")) { // ... }
While the comparison does succeed on the code above, it fails on the similar code below, 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
Comparing or inspecting the string representation of floating-point values may have unexpected results.
Rule |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
---|---|---|---|---|---|
NUM11-J |
low |
likely |
medium |
P6 |
L2 |
Related Vulnerabilities
Hibernate Validator bug report HV-192 describes a violation of this rule.
Bibliography
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="3f474e8f-2541-47e8-a1fe-529cccdd75cb"><ac:plain-text-body><![CDATA[ |
[[API 2006 |
AA. References#API 06]] |
]]></ac:plain-text-body></ac:structured-macro> |
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="7e4b4b07-6284-42a0-8f62-58ec6fc8282e"><ac:plain-text-body><![CDATA[ |
[[JLS 2005 |
AA. References#JLS 05]] |
]]></ac:plain-text-body></ac:structured-macro> |