All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.sonar.l10n.java.rules.squid.S1244.html Maven / Gradle / Ivy

The newest version!

Floating point math is imprecise because of the challenges of storing such values in a binary representation. Even worse, floating point math is not associative; push a float or a double through a series of simple mathematical operations and the answer will be different based on the order of those operation because of the rounding that takes place at each step.

Even simple floating point assignments are not simple:

float f = 0.1; // 0.100000001490116119384765625
double d = 0.1; // 0.1000000000000000055511151231257827021181583404541015625

(Results will vary based on compiler and compiler settings);

Therefore, the use of the equality (==) and inequality (!=) operators on float or double values is almost always an error. Instead the best course is to avoid floating point comparisons altogether. When that is not possible, you should consider using one of Java's float-handling Numbers such as BigDecimal which can properly handle floating point comparisons. A third option is to look not for equality but for whether the value is close enough. I.e. compare the absolute value of the difference between the stored value and the expected value against a margin of acceptable error. Note that this does not cover all cases (NaN and Infinity for instance).

This rule checks for the use of direct and indirect equality/inequailty tests on floats and doubles.

Noncompliant Code Example

 
float myNumber = 3.146; 
if ( myNumber == 3.146f ) { //Noncompliant. Because of floating point imprecision, this will be false 
  // ... 
} 
if ( myNumber != 3.146f ) { //Noncompliant. Because of floating point imprecision, this will be true 
  // ... 
} 

if (myNumber < 4 || myNumber > 4) { // Noncompliant; indirect inequality test
  // ...
}

float zeroFloat = 0.0f;
if (zeroFloat == 0) {  // Noncompliant. Computations may end up with a value close but not equal to zero.
}

Compliant Solution

float zeroFloat = 0.0f;
if (Float.floatToRawIntBits(zeroFloat) == 0) { //Compliant for comparisons of zero. Using bit comparison ensures we compare zero values
}

Exceptions

Since NaN is not equal to itself, the specific case of testing a floating point value against itself is a valid test for NaN and is therefore ignored.

float f;
double d;
if(f != f) { // Compliant; test for NaN value
  System.out.println("f is NaN");
} else if (f != d) { // Noncompliant
  // ...
}

See

  • MISRA C:2004, 13.3 - Floating-point expressions shall not be tested for equality or inequality.
  • MISRA C++:2008, 6-2-2 - Floating-point expressions shall not be directly or indirectly tested for equality or inequality




© 2015 - 2025 Weber Informatics LLC | Privacy Policy