Because floatingpoint numbers represent real numbers, it is often mistakenly assumed that they can represent any simple fraction exactly. Floatingpoint numbers are subject to representational limitations just as integers are, and binary floatingpoint numbers cannot represent all real numbers exactly, even if they can be represented in a small number of decimal digits.
In addition, because floatingpoint numbers can represent large values, it is often mistakenly assumed that they can represent all significant digits of those values. To gain a large dynamic range, floatingpoint numbers maintain a fixed number of precision bits (also called the significand) and an exponent, which limit the number of significant digits they can represent.
Different implementations have different precision limitations, and to keep code portable, floatingpoint variables must not be used as the loop induction variable. See Goldberg's work for an introduction to this topic [Goldberg 1991].
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).
Noncompliant Code Example
In this noncompliant code example, a floatingpoint 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 floatingpoint number. Depending on the implementation, the loop may iterate 9 or 10 times.
For example, when compiled with GCC or Microsoft Visual Studio 2013 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 floatingpoint value is derived:
Noncompliant Code Example
In this noncompliant code example, a floatingpoint loop counter is incremented by an amount that is too small to change its value given its precision:
On many implementations, this produces an infinite loop.
Compliant Solution
In this compliant solution, the loop counter is an integer from which the floatingpoint value is derived. The variable x
is assigned a computed value to reduce compounded rounding errors that are present in the noncompliant code example.
Risk Assessment
The use of floatingpoint variables as loop counters can result in unexpected behavior .
Rule  Severity  Likelihood  Remediation Cost  Priority  Level 

FLP30C  Low  Probable  Low  P6  L2 
Automated Detection
Tool  Version  Checker  Description 

Astrée  17.04i  forloopfloat  Fully checked 
Clang  3.9  certflp30c  Checked by clangtidy 
CodeSonar  4.4  LANG.STRUCT.LOOP.FPC  Floattyped loop counter 
Compass/ROSE 



Coverity  2017.07  MISRA C 2004 Rule 13.4 MISRA C 2012 Rule 14.1  Implemented 
ECLAIR  1.2  CC2.FLP30  Fully implemented 
Klocwork  2017  MISRA.FOR.COND.FLT MISRA.FOR.COUNTER.FLT  
LDRA tool suite  9.5.6  39 S  Fully implemented 
Parasoft C/C++test  9.5  MISRA065  Fully implemented 
Polyspace Bug Finder  R2016a  MISRA2012RULE14_1, MISRA2012DIR1_1  Fully implemented 
PRQA QAC  9.3  3340, 3342  Partially implemented 
PRQA QAC++  4234  
RuleChecker  17.04i  forloopfloat  Fully checked 
SonarQube C/C++ Plugin  3.11  S2193  Fully implemented 
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Related Guidelines
SEI CERT C++ Coding Standard  FLP30CPP. Do not use floatingpoint variables as loop counters 
CERT Oracle Secure Coding Standard for Java  NUM09J. Do not use floatingpoint variables as loop counters 
ISO/IEC TR 24772:2013  FloatingPoint Arithmetic [PLF] 
MISRA C:2012  Directive 1.1 (required) Rule 14.1 (required) 
Bibliography
[Aho 1986]  
[Goldberg 1991]  
[Lockheed Martin 05]  AV Rule 197 
9 Comments
Alex Volkovitsky
is this line in the second CCE a violation of FLP33C. Convert integers to floating point for floating point operations?
Robert Seacord
I don't think so. As long as one of the arguments is a floating point number, the calculation should be performed as a floating point operation.
Martin Sebor
As I commented elsewhere, I see no real problem with either noncompliant example since they both use the lessthan or equal operator (i.e., the loops are guaranteed to terminate). An example that, IMO, demonstrates the problem better is one that uses [in]equality since, unlike integer arithmetic, floating point arithmetic is inexact:
Dhruv Mohindra
I believe the rationale here is that a programmer might expect the loop to execute 10 times but it executes only 9 times. At least in Java and VC++ 2005.
Martin Sebor
I see – very tricky! That hadn't even occurred to me despite the fact that it's mentioned below the noncompliant example. I should read these guidelines before the CSCG ones!
Maybe the example could be enhanced to make this more obvious. How's this:
Phil Dennis
This page doesn't really make it clear that cumulative rounding error is an issue that cannot be addressed by the usual advice for avoiding an exact comparison of floating point numbers.
Readers might think that the first noncompliant example could be 'fixed' by changing the termination condition to 'x < 10.05' (as I did at first.) Here is a proposed replacement which makes it clear that this 'fix' would not be generally applicable:
When compiled on gcc for x86 this will iterate 10,001 times.
David Svoboda
Added a reference to [Goldberg 1991] to provide background material for why fps should not be loop counters. (We also have recommendations addressing this like FLP00C. Understand the limitations of floatingpoint numbers).
Phil Dennis
Also, the solution for the second noncompliant example seems problematic. While it addresses the loop termination issue, we are still left with a value of x that may or may not be incrementing depending on the implementation, and if it is incrementing, will certainly be subject to cumulative rounding errors.
Here's an improved solution for the second noncompliant example:
David Svoboda
Fixed the 2nd compliant solution as you suggest, thanks!