Main Content

Memory comparison of float-point values

Object representation of floating-point values can be different (same) for equal (not equal) floating-point values

Description

This defect occurs when you compare the object representation of floating-point values or the object representation of structures containing floating-point members. When you use the functions memcmp, bcmp, or wmemcmp to perform the bit pattern comparison, the defect is raised.

Risk

The object representation of floating-point values uses specific bit patterns to encode those values. Floating-point values that are equal, for instance -0.0 and 0.0 in the IEC 60559 standard, can have different bit patterns in their object representation. Similarly, floating-point values that are not equal can have the same bit pattern in their object representation.

Fix

When you compare structures containing floating-point members, compare the structure members individually.

To compare two floating-point values, use the == or != operators. If you follow a standard that discourages the use of these operators, such as MISRA™, ensure that the difference between the floating-point values is within an acceptable range.

Examples

expand all

#include <string.h> 

typedef struct {
    int i;
    float f;
} myStruct;

extern void initialize_Struct(myStruct *);

int func_cmp(myStruct *s1, myStruct *s2) {
/* Comparison between structures containing 
* floating-point members */
    return memcmp 
        ((const void *)s1, (const void *)s2, sizeof(myStruct));
}

void func(void) {
    myStruct s1, s2;
    initialize_Struct(&s1);
    initialize_Struct(&s2);
    (void)func_cmp(&s1, &s2);
}

In this example, func_cmp() calls memcmp() to compare the object representations of structures s1 and s2. The comparison might be inaccurate because the structures contain floating-point members.

Correction — Compare Structure Members Individually

One possible correction is to compare the structure members individually and to ensure that the difference between the floating-point values is within an acceptable range defined by ESP.

#include <string.h> 
#include <math.h>

typedef struct {
    int i;
    float f;
} myStruct;

extern void initialize_Struct(myStruct *);

#define ESP 0.00001

int func_cmp(myStruct *s1, myStruct *s2) {

/*Structure members are compared individually */	
    return ((s1->i == s2->i) &&
            (fabsf(s1->f - s2->f) <= ESP)); 
}

void func(void) {
    myStruct s1, s2;
    initialize_Struct(&s1);
    initialize_Struct(&s2);
    (void)func_cmp(&s1, &s2);
}

Result Information

Group: Programming
Language: C | C++
Default: Off
Command-Line Syntax: MEMCMP_FLOAT
Impact: Low

Version History

Introduced in R2018a