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

Compare with Current View Page History

« Previous Version 52 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. Depending on the implementation, the loop may iterate 9 or 10 times.

for (float x = 0.1f; x <= 1.0f; x += 0.1f) {
  /* loop may iterate 9 or 10 times */
}

For example, when compiled with GCC or Microsoft Visual C++ 2005 Express version 8.0, and executed on an x86 processor, the loop is evaluated 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;
  /* loop iterates exactly 10 times */
}

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) {
  /* loop may not terminate */
}

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;
  /* loop iterates exactly 10 times */
}

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

9.7.1

39 S

Fully Implemented

Tool

Version

Checker

Description

9.7.1

 

 

Fortify SCA

V. 5.0

 

can detect violations of this rule with CERT C Rule Pack

Compass/ROSE

 

 

 

Related Vulnerabilities

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

Related Guidelines

CERT C++ Secure Coding Standard: FLP30-CPP. Do not use floating point variables as loop counters

The CERT Oracle Secure Coding Standard for Java: NUM09-J. Do not use floating-point variables as loop counters

ISO/IEC 14882:2003 Sections 2.13.3, "Floating literals," and 3.9.1, "Fundamental types"

ISO/IEC TR 24772 "PLF Floating Point Arithmetic"

MISRA Rules 13.3 and 13.4

Bibliography

[Lockheed Martin 05] AV Rule 197, "Floating point variables shall not be used as loop counters"


FLP06-C. Understand that floating-point arithmetic in C is inexact      FLP30-C. Do not use floating point variables as loop counters      FLP30-C. Do not use floating point variables as loop counters

  • No labels