You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 17 Next »

Because floating-point numbers can represent fractions, it is often mistakenly assumed that they can represent any simple fraction exactly. In fact, floating-point numbers are subject to precision limitations just as integers are, and binary floating-point numbers cannot represent all decimal fractions exactly, even if the fractions can be represented in a small number of decimal digits.

In addition, because floating-point numbers can represent large values, it is often mistakenly assumed that they can represent all digits of those values. To gain a large dynamic range, floating-point numbers maintain a fixed number of bits of precision and an exponent. Incrementing a large floating-point value may not change that value within the available precision. Consequently, floating-point variables should not be used as loop counters.

Noncompliant Code Example

This noncompliant code example uses a floating-point variable as a loop counter. The decimal number 0.1 is a repeating fraction in binary and cannot be exactly represented as a binary floating-point number.

for (float x = 0.1f; x <= 1.0f; x += 0.1f) {
  // ... 
}

This loop executes only nine times. (If the value of x is printed inside the loop, the following values appear: 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.70000005, 0.8000001, 0.9000001.)

Compliant Solution

This compliant solution uses an integer loop counter from which the floating-point value is derived.

for (int count = 1; count <= 10; count += 1) {
  float x = count/10.0f;
  // ...
}

Noncompliant Code Example

This noncompliant code example uses a floating-point loop counter that is incremented by an amount that is too small to change its value given the precision.

for (float x = 100000001.0f; x <= 100000010.0f; x += 1.0f) {
  /* ... */
}

This produces an infinite loop.

Compliant Solution

This compliant solution uses an integer loop counter from which the floating-point value is derived. Additionally, a double is used instead of a float to gain enough precision.

for (int count = 1; count <= 10; count += 1) {
  double x = 100000000.0 + count;
  /* ... */
}

Risk Assessment

Using floating-point loop counters can lead to unexpected behavior.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

FLP30- J

low

probable

low

P6

L2

Automated Detection

TODO

Related Vulnerabilities

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

Other Languages

This rule appears in the C Secure Coding Standard as FLP30-C. Do not use floating point variables as loop counters.

This rule appears in the C++ Secure Coding Standard as FLP30-CPP. Do not use floating point variables as loop counters.

References

[[JLS 05]] Section 4.2.3, Floating-Point Types, Formats, and Values
[[Bloch 05]] Puzzle 34: Down for the Count


FLP04-J. Check floating point inputs for exceptional values      07. Floating Point (FLP)      FLP31-J. Convert integers to floating point for floating point operations

  • No labels