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

Compare with Current View Page History

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

Noncompliant Code Example

In this noncompliant code example, a floating-point variable is used 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) {
  /* ... */
}

If this code is compiled with Microsoft Visual C++ 2005 Express version 8.0, and executed on an IA-32 machine running Windows XP, this loop is executed only nine times.

Compliant Solution

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

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

Noncompliant Code Example

In this noncompliant code 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 from which the floating-point value is derived. Additionally, a double is used instead of a float to gain enough precision.

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

Risk Assessment

The use of floating-point variables as loop counters can result in unexpected behavior.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

FLP30-C

low

probable

low

P6

L2

Automated Detection

The LDRA tool suite V 7.6.0 can detect violations of this rule.

Fortify SCA Version 5.0 with CERT C Rule Pack can detect violations of this rule.

Compass/ROSE can detect violations of this rule.

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-CPP. Do not use floating point variables as loop counters.

This rule appears in the Java Secure Coding Standard as FLP31-J. Do not use floating point variables as loop counters.

References

[[ISO/IEC 14882:2003]] Sections 2.13.3, "Floating literals," and 3.9.1, "Fundamental types"
[[ISO/IEC PDTR 24772]] "PLF Floating Point Arithmetic"
[[Lockheed Martin 05]] AV Rule 197, "Floating point variables shall not be used as loop counters"
[[MISRA 04]] Rules 13.3 and 13.4


FLP03-C. Detect and handle floating point errors      05. Floating Point (FLP)      FLP31-C. Do not call functions expecting real values with complex values

  • No labels