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

Compare with Current View Page History

« Previous Version 3 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 they 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.

Different implementations have different precision limitations, and to keep code portable, floating point variables should not be used as loop counters.

Non-Compliant Code Example

In this non-compliant example, a floating point variable has been used as a loop counter.  The decimal number 0.1 is a repeating fraction in binary, and therefore cannot be represented exactly in a binary floating point number.

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

Implementation Specific Details

Under Microsoft Visual Express version 8.0 running on an x86 machine with Windows XP, this loop was executed only nine times.

Compliant Solution

In this compliant solution, the loop counter is an integer.  The floating point value is derived from the integer.

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

Non-Compliant Code Example

In this non-compliant example, a floating point loop counter is incremented by an amount that is too small to change its value given its precision.

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

On many implementations, this produces an infinite loop.

Compliant Solution

In this compliant solution, the loop counter is an integer, the floating point value is derived from it, and a double rather than a float is used to gain enough precision.

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

Risk Assessment

Using floating point loop counters could lead to unexpected behavior.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

FLP31-C

1 (low)

1 (unlikely)

3 (low)

P3

L3

References

[[ISO/IEC 14882-2003]] Sections 2.13.3, "Floating literals," and 3.9.1, "Fundamental types"
[[Lockheed Martin 05]] AV Rule 197, "Floating point variables shall not be used as loop counters."

  • No labels