メインコンテンツ

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

等号演算子による浮動小数点の比較

浮動小数点変数の不正確な比較

説明

この欠陥は、等式演算 (==) または不等式演算 (!=) に浮動小数点数が使用された場合に発生します。

Polyspace® では、以下の場合に浮動小数点数の等価演算および不等式演算の欠陥を報告しません。

  • 2 つの浮動小数点定数の間で比較が行われている。

        float flt = 1.0;
        if (flt == 1.1)
  • 定数と、有限のごく少数の値を取りうる変数の間で比較が行われている。

    float x;
    
    int rand = random(); 
    switch(rand) { 
    case 1: x = 0.0; break; 
    case 2: x = 1.3; break; 
    case 3: x = 1.7; break; 
    case 4: x = 2.0; break; 
    default: x = 3.5; break; }
    …
    if (x==1.3) 
  • 整数値のみを含む浮動小数点式の間で比較が行われている。

    float x = 0.0;
    for (x=0.0;x!=100.0;x+=1.0) {
    …
    if (random) break;
    }
    
    if (3*x+4==2*x-1)
    …
    if (3*x+4 == 1.3)
  • オプション フラグ -detect-bad-float-op-on-zero を使用しない限り、オペランドの 1 つは 0.0 です。

    /* Defect detected when
    you use the option flag */
    
    if (x==0.0f) 

    ユーザー インターフェイスから解析を実行している場合は、[構成] ペインの [詳細設定] ノードにある [その他] フィールドにこのオプションを入力できます。Otherを参照してください。

    コマンド ラインで、解析コマンドにフラグを追加します。

    polyspace-bug-finder -sources filename ^
    -checkers BAD_FLOAT_OP -detect-bad-float-op-on-zero

リスク

浮動小数点の表現は不正確で丸め誤差を伴うため、2 つの浮動小数点値の等価性または非等価性のチェックは予期しない結果を返す可能性があります。

修正方法

次のように浮動小数点値の等価性をチェックする代わりに、

if (val1 == val2)
以下のように値の差が事前定義された許容誤差値 (たとえば、float.h に定義されている値 FLT_EPSILON) より小さいことをチェックします。
#include <float.h>
if(fabs(val1-val2) < FLT_EPSILON)

以下の修正例を参照してください。

問題を修正しない場合は、改めてレビューされないように結果またはコードにコメントを追加します。詳細は、以下を参照してください。

すべて展開する

#include <stdio.h>
#include <math.h>
#include <float.h>

void func(void)
{
    float f;
    for (f = 1.0; f != 2.0; f = f + 0.1)    
        (void)printf("Value: %f\n", f);
}

この関数では、for ループで停止メカニズムとして f と数値 2.0 の非等価性をテストします。浮動小数点の表現は不正確なため、反復回数は特定が難しいか、無限大の可能性があります。

修正 — 演算子を変更

1 つの修正方法として、厳密性の低い別の演算子を使用することができます。たとえば、>= または <= などの不等式演算です。

#include <stdio.h>
#include <math.h>
#include <float.h>

void func(void)
{
    float f;
    for (f = 1.0; f <= 2.0; f = f + 0.1)    
        (void)printf("Value: %f\n", f);
}

結果情報

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

バージョン履歴

R2013b で導入