Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Converting a value of type float to the type double is a widening primitive conversion. Refer to the guideline INT33-J. Do not cast numeric types to wider floating-point types without range checking for more details about such conversions. If the value of the float variable must be represented exactly using the double type, an explicit assignment is inappropriate. Note that this is a problem that results from the limited capacity of computers in representing floating point values preciselyString representations of floating-point numbers should not be compared or inspected. If they are used, significant care needs to be taken to ensure expected behavior.

Noncompliant Code Example

...

(String Comparison)

This noncompliant code example incorrectly compares the decimal string literal generated by 1/10000.0. The string produced is not 0.0001 but rather 1.0E-4. Wiki MarkupIn this noncompliant code example, the programmer attempts to convert the fractional value {{1/3}} (represented by a variable of type {{float}}) to the {{double}} type. The correct representation of this fraction in floating point arithmetic is 0.33333334 (the last digit 4, is rounded up). When converted to {{double}}, instead of observing a value such as 0.3333333400000000 or 0.333333333333333, the programmer obtains an unexpected value because floating point arithmetic in Java _rounds to the nearest_, a mode defined by the IEEE 754 floating point standard. If the exact value lies midway between two valid floating point values, the lower one (with the least significant bit as 0) is chosen. If it is more than midway, a small positive error is introduced, else a small negative error. \[[Mak 02|AA. Java References#Mak 02]\]

Code Block
bgColor#FFCCCC

double d;
float f int i = 1/3f;
String //s Contains the value 0.33333334
d = f; // Now contains the value 0.3333333432674408

Compliant Solution

= Double.valueOf(i / 10000.0).toString();
if (s.equals("0.0001")) {
  // ...
}

Compliant Solution (String Comparison)

This compliant solution uses the BigDecimal class to avoid the conversion into scientific notation. It then performs a numeric comparison, which passes as expectedIf the exact value must be preserved, the string representation of the floating point number must be obtained. This can be converted to the double type without losing the initial precision.

Code Block
bgColor#ccccff

double d;
float fint i = 1/3f; // Contains the value 0.33333334
d = Double.valueOf(String.valueOf(f)); // Now contains the value 0.33333334

Risk Assessment


BigDecimal d = new BigDecimal(Double.valueOf(i / 10000.0).toString());
if (d.compareTo(new BigDecimal("0.0001")) == 0) {
  // ...
}

Risk Assessment

Comparing or inspecting the string representation of floating-point values may have unexpected resultsConverting from float to double type when exact values are required can affect the precision of the converted value.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

FLP05

NUM11-J

low

Low

likely

Likely

medium

Medium

P6

L2

Automated Detection

TODO

Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this rule on the CERT website.

References

Wiki Markup
\[[API 06|AA. Java References#API 06]\] 
\[[JLS 05|AA. Java References#JLS 05]\] 
\[[Mak 02|AA. Java References#Mak 02]\] Section 3.7 "Another Look at Roundoff Errors"


Android Implementation Details

Comparing or inspecting the string representation of floating-point values may have unexpected results on Android.

Bibliography


...

Image Added Image Added Image AddedFIO36-J. Do not create multiple buffered wrappers on an InputStream      09. Input Output (FIO)      09. Input Output (FIO)