Versions Compared

Key

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

Floating-point variables must not be used as loop counters. Limited-precision IEEE 754 floating-point types cannot represent

  • all All simple fractions exactly.
  • all All decimals precisely, even when the decimals can be represented in a small number of digits.
  • all All digits of large values, meaning that incrementing a large floating-point value might not change that value within the available precision.

For the purpose of this rule, a loop counter is an induction variable that is used as an operand of a comparison expression that is used as the controlling expression of a do, while or for loop. An induction variable is a variable that gets increased or decreased by a fixed amount on every iteration of a loop [Aho 1986]. Furthermore, the change to the variable must occur directly in the loop body (rather than inside a function executed within the loop.)

This rule is a subset of NUM04-J. Do not use floating-point numbers if precise computation is required.

Noncompliant Code Example

This noncompliant code example uses a floating-point variable as a loop counter. The decimal number 0.1 cannot be precisely represented as a float or even as a double.

Code Block
bgColor#FFCCCC

for (float x = 0.1f; x <= 1.0f; x += 0.1f) {
  System.out.println(x);
}

Because 0.1f is rounded to the nearest value that can be represented in the value set of the float type, the actual quantity added to x on each iteration is somewhat larger than 0.1. Consequently, the loop executes only nine times and typically fails to produce the expected output.

...

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

Code Block
bgColor#ccccff

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

...

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

Code Block
bgColor#FFCCCC

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

...

This compliant solution uses an integer loop counter from which the floating-point value is derived. Additionally, it uses a double to ensure that the available precision suffices to represent the desired values. The solution also runs in strict floating-point (FP-strict) mode to guarantee portability of its results (see NUM53-J. Use the strictfp modifier for floating-point calculation consistency across platforms for more information).

Code Block
bgColor#ccccff

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

...

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

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

NUM09-J

low

Low

probable

Probable

low

Low

P6

L2

Automated Detection

Automated detection of floating-point loop counters is straightforward.

Related Guidelines

The CERT C Secure Coding Standard

FLP30-C.
ToolVersionCheckerDescription
Parasoft Jtest
Include Page
Parasoft_V
Parasoft_V
CERT.NUM09.FPLI
Do not use floating point variables as loop
countersThe CERT C++ Secure
indices
PVS-Studio

Include Page
PVS-Studio_V
PVS-Studio_V

V6108

Related Guidelines

SEI CERT C Coding Standard

FLP30-

CPP [

C. Do not use floating-point variables as loop counters

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="a1804d15-b4ff-4713-86c2-8e228be43db1"><ac:plain-text-body><![CDATA[

ISO/IEC TR 24772:2010

http://www.aitcnet.org/isai/]

Floating-point Arithmetic [PLF]

]]></ac:plain-text-body></ac:structured-macro>

Bibliography

[Aho 1986]

[Bloch 2005]

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="51ef9ea2-93fc-4719-b769-2d5ab121fa7a"><ac:plain-text-body><![CDATA[

[[Bloch 2005

AA. Bibliography#Bloch 05]]

Puzzle 34, "Down for the

count

Count"

[JLS 2015]

§4

]]></ac:plain-text-body></ac:structured-macro>

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="94f73d42-2386-483b-98a1-785f633f0cb1"><ac:plain-text-body><![CDATA[

[[JLS 2005

AA. Bibliography#JLS 05]]

[§4

.2.3, "Floating-Point Types, Formats, and Values

http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.2.3]

]]></ac:plain-text-body></ac:structured-macro>

"

[Seacord 2015]


...

Image Added Image Added Image Removed      03. Numeric Types and Operations (NUM)