メインコンテンツ

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

浮動小数点値のメモリ比較

浮動小数点値のオブジェクト表現が、等しい (等しくない) 浮動小数点値で異なる (同じである)

説明

この欠陥は、浮動小数点値のオブジェクト表現または浮動小数点メンバーを含む構造体のオブジェクト表現が比較された場合に発生します。関数 memcmpbcmp、または wmemcmp を使用してビット パターン比較を実行すると、欠陥が報告されます。

リスク

浮動小数点値のオブジェクト表現では、特定のビット パターンを使用してこれら値を符号化します。IEC 60559 規格での -0.00.0 など、等しい浮動小数点値がそれぞれのオブジェクト表現では異なるビット パターンをもつことがあります。同様に、等しくない浮動小数点値がオブジェクト表現では同じビット パターンをもつこともあります。

修正方法

浮動小数点メンバーを含む構造体を比較する場合、構造体のメンバーを個別に比較します。

2 つの浮動小数点値を比較するには、== または != 演算子を使用します。MISRA™ など、これらの演算子の使用を推奨していない規格に従う場合は、浮動小数点値間の差が許容範囲内に収まるようにします。

すべて展開する

#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);
}

この例では、func_cmp()memcmp() を呼び出して、構造体 s1 および s2 のオブジェクト表現を比較しています。この比較は、構造体に浮動小数点メンバーが含まれているため、正確ではない可能性があります。

修正 — 構造体メンバーを個別に比較

1 つの修正方法として、構造体メンバーを個別に比較し、浮動小数点値間の差が 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);
}

結果情報

グループ: プログラミング
言語: C | C++
既定値: オフ
コマンド ライン構文: MEMCMP_FLOAT
影響度: Low

バージョン履歴

R2018a で導入