Floating-point variables must not be used as loop counters. Limited-precision IEEE 754 floating-point types cannot represent
- All simple fractions exactly.
- All decimals precisely, even when the decimals
...
- can be represented in a small number of
...
- digits.
...
- 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 Consequently, floating-point variables should not be used as loop counters.
Noncompliant Code Example
In this This noncompliant code example , uses 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 precisely represented as a binary floating-point number float
or even as a double
.
Code Block | ||
---|---|---|
| ||
for (float x = 0.1f; x <= 1.0f; x += 0.1f) { // System... out.println(x); } |
This loop is executed 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
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.
Compliant Solution
This compliant solution uses an integer loop counter from which the desired In this compliant solution, the loop counter is an integer from which the floating-point value is derived.:
Code Block | ||
---|---|---|
| ||
for (int count = 1; count <= 10; count += 1) { float x = count/10.0f; // System.out..println(x); } |
Noncompliant Code Example
In this 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 its the precision.:
Code Block | ||
---|---|---|
| ||
for (float x = 100000001.0f; x <= 100000010.0f; x += 1.0f) {
/* ... */
}
|
This produces an infinite loopThe code loops forever on execution.
Compliant Solution
In this This compliant solution , the uses an integer loop counter is an integer from which the floating-point value is derived. Additionally, it uses a double
is used instead of a float
to gain enough precision. 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 | ||
---|---|---|
| ||
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 |
---|
NUM09-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
...
Automated detection of floating-point loop counters is straightforward.
...
Tool | Version | Checker | Description | |||||
---|---|---|---|---|---|---|---|---|
Parasoft Jtest |
| CERT.NUM09.FPLI |
Do not use floating point variables as loop |
...
indices | |||||||||
PVS-Studio |
| V6108 |
Related Guidelines
...
...
References
...
ISO/IEC TR 24772:2010 | Floating-point Arithmetic [PLF] |
Bibliography
...
...
...
...
...
...
...
attempt comparisons with NaN 06. Floating Point (FLP) FLP31-J. Convert integers to floating point for floating point operations