TICS Coding Standard Viewer 
TIOBE Software Quality Framework
Print-friendly version
©TIOBE Software www.tiobe.com
 
ASML C Coding Standard
Search

Rule:  6.5.9.bChecked automatically with code checker

Synopsis:Floating point expressions shall not be compared using the "==", "!=" operators. Floating point expressions shall be compared using special functions.
Language:C
Severity Level:3
Category:Expressions


Description:

Justification

Comparing floating point expressions for equality or inequality is a notorious and well-documented source of software system failures.

Example 1

#include "floatcompare.h"

double CCBB_calculate(void);
double d;

d = CCBB_calculate();
if (d != 0.0F) /* WRONG: d might be close to 0 */
...
if (!dbl_equal(d, 0.0)) /* RIGHT */
...

Example 2

double d;

for (d = 0.0; d != 30.0; d = d + 1.0) /* WRONG, d will never become exactly 30.0 */
   /* any statement */
}

Example 3

#include "floatcompare.h"

double min = 10.0;
double sns;
double eps = 0.01; /* epsilon: 10% of sensor resolution */

sns = CCBB_read_sensor();
if (dbl_equal_relative(sns, min, eps)) /* RIGHT */

Example 4

double d;
...
if (d == 0.0) /* WRONG */
{
   /* Any statement */
}

Example 5

#define CCBB_D_EPSILON (1.0e-11) /* 1% of smallest resolution of d */

ccbb_get_d(d);

if (dbl_equal_absolute(d, end_d, CCBB_D_EPSILON)) /* RIGHT */
{
   /* Any statement */
}

Note

In some code, a variable is tested on 0.0 before it is used in a division. It is certain that the programmer had a good intention, but still the code can be criticized. If you divide by a very small number, an overflow can occur. The same can be said about testing for NAN.

It is rather strange to say that 0.0 is a special situation, while 1 * 10-12 isn't.

A good programming practice is to test the initial values on their range. If during a calculation there is some doubt if the new values are still within a reasonable range, a new range test can be made. If this way of programming is well thought through, then it is not necessary to test on 0.0 before every division. Like in programming with pointers, you do not test on NULL for every pointer dereference.

It does occur that a float is tested on 0.0 to see if something has been initialised. In general, this is bad coding practice because the value has a second meaning in such case. First, it says if something has been initialized and second, it contains the result of a measurement (that value should never be 0.0!). This problem is difficult to remove in old code.