You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 5 Next »

The object representation for floating-point values is implementation defined. However, an implementation which defines the __STDC_IEC_559__ macro shall conform to the IEC 60559 floating-point standard, and uses what is frequently referred to as IEEE 754 floating-point arithmetic [ISO/IEC 9899:2011]. The floating-point object representation used by IEC 60559 is one of the most common floating-point object representations in use today.

All floating-point object representations uses specific bit patterns to encode the value of the floating-point number being represented. However, equivalence of floating-point values is not encoded solely by the bit pattern used to represent the value. For instance, if the floating-point format supports negative zero values (as IEC 60559 does), the values -0.0 and 0.0 are equivalent and will compare as equal, but the bit patterns used in the object representation are not identical. Similarly, if two floating-point values are both (the same) NaN, they will not compare as equal, despite the bit patterns being identical, because they are not equivalent.

Do not compare floating-point object representations directly, such as by calling memcmp(), or its moral equivalents. Instead, the equality operators (== and !=) should be used to determine if two floating-point values are equivalent.

Noncompliant Code Example

In this noncompliant code example, memcmp() is used to compare two structures for equality. However, since the structure contains a floating-point object, this code may not behave as the programmer intended.

#include <stdbool.h>
#include <string.h>
 
struct S {
  int i;
  float f;
};
 
bool are_equal(const struct S *s1, const struct S *s2) {
  if (!s1 && !s2)
    return true;
  else if (!s1 || !s2)
    return false;
  return 0 == memcmp(s1, s2, sizeof(struct S));
}

Compliant Solution

In this compliant solution, the structure members are compared individually:

#include <stdbool.h>
#include <string.h>
 
struct S {
  int i;
  float f;
};
 
bool are_equal(const struct S *s1, const struct S *s2) {
  if (!s1 && !s2)
    return true;
  else if (!s1 || !s2)
    return false;
  return s1->i == s2->i &&
         s1->f == s2->f;
}

Risk Assessment

Using the object representation of floats for comparisons can lead to incorrect equality results, which can lead to unexpected behavior and incorrect results.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

FLP37-C

Low

Unlikely

Medium

P2

L3

Automated Detection

Tool

Version

Checker

Description

LDRA tool suite9.7.1618 SEnhanced Enforcement

Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this rule on the CERT website.

Related Guidelines

  

Bibliography

[ISO/IEC 9899:2011]Annex F, "IEC 60559 floating-point arithmetic"

 


  

  • No labels