2012-02-09 7 views
2

こんにちは私は、リリース64ビットのリリースビルドでのみ奇妙なbehviorを与えている機能があります。 32bitはすべてのケースで動作し、64bitはデバッグで動作します。とにかく元のコードHERESに、値の値は、5または100等:などの実数であるIsNanとVS2010の値が64bitの場合

static void 
Foo(char **pInOut, unsigned int key, double value) 
{ 
if (value == -HUGE_VAL) 
    return; 

if (value != value) 
    return; 

// Does stuff that isn't happening 
} 

私が遊んでいたと私は値を置き換える=と値:!今

static void 
Foo(char **pInOut, unsigned int key, double value) 
{ 
if (value == -HUGE_VAL) 
    return; 

if (_isnan(value)) 
    return; 

// Does stuff that happens now 
} 

それは働いている。値!=値はまだ有効ですか?私は何かを逃しています...私はちょうど古い方法が動作しない理由を見ていない?

答えて

3

NaNの場合は、value!=valueがtrueになります。しかし、NaNでない場合、value!=valueが偽になることは保証されません。

+0

これは64ビットビルドにのみ影響します。このコードは何年も存在しており、絶えず使用されていますが、今まで問題に遭遇したことはありませんでしたか? – user1198542

+0

それはUBの問題です。突然それが起こらない限り、あなたが期待していることを正確に行います。だからあなたはそれを避けるべきです。 –

-1

浮動小数点値の比較は直感的ではありません。各浮動小数点値には、以前の計算と処理の影響を受ける単なるおおよその表現(いくつかの値は正確ですが)が含まれています。 HUGE_VALでも、FPUのモードと値の取り扱いによって精度が低下する可能性があります。

代わりに、epsilon comparisonを使用して浮動小数点値を比較してください。 is_nan()関数は特殊ビットの浮動小数点値を検査する正確な方法であり、非数の特殊表現として指定します。

+1

まあ、私はOPが浮動小数点値の精度問題を認識していると思います。 'value'の値は不正確であっても(それが何であっても)、それ自体の値と同じでなければなりません(NaNを除く)。イプシロンですべてをスパムするだけでは良い一般的なアドバイスではありません。多くの場合、単純なバイナリ比較は十分であり(または必要であっても)、コンテキストに完全に依存します。だから、これは決して質問に答えません。ちょうど "OMG彼は2桁の浮動小数点を比較しています!"と泣く前に質問をお読みください。 –

+2

実際には、それが自分の価値に等しいことを要求するルールはなく、そうでないかもしれない理由があります。たとえば、この[GCCバグレポート](http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31008)を参照してください。等価性のテストは、ある値をレジスタにロードし、それをメモリ内の他の値と比較することによって実装する必要があります。ロード処理によって、数値のバイナリ表現が変更される可能性があります(メモリフォーマットの精度がレジスタフォーマットと異なる場合があります)。 –

関連する問題