2016-07-13 18 views
5

私はバイナリ意味x0==x1y0==y1、(及び==有すると仮定すると、次のC式(変数は32ビット浮動小数点数である)浮動小数点ゼロ(IEEE 754不変?)

float result = (x1 - x0) * (y2 - y0) - (x2 - x0) * (y1 - y0) 

を有します表現のアイデンティティー)では、式が必ずゼロに評価されるという事実に頼ることができますか(浮動小数点のすべてのビットが0に設定されているかのように)?言い換えれば、次の不変量が常に成立すると仮定できますか?

memcmp(&a, &b, sizeof(float) == 0 => memcmp(a-b, (uint32_t)0, sizeof(float)) == 0 
0*a == 0.0 

すべての値は有限の数値(無限大またはNaN)でないとは限りません。

編集:回答で指摘したように、0での乗算は符号付きゼロを生成できます。私はまだすなわち、式の結果は、FP-比較ルールを使用して0.0に等しいであろうという事実に頼ることができます。:

(result == 0.0) 

編集1:置き換えタイプは、より良い質問を説明するために呼び出すmemcmpでキャストします。

P.S.私は互換性のあるC11コンパイラのみに制限しています。私はSTDC_IEC_559サポートに頼っても構わないと思っています。

+0

'y2 - y0'と' x2 - x0'は有限であるとも仮定できますか? –

+0

@OliverCharlesworth:はい。そうでなければ、結果は未定義です。 – MrMobster

+0

どのタイプが 'a'と' b'ですか?それらが 'uint32_t'でない場合、あなたのコードは未定義のビヘイビアを呼び出します(実効型ルールの違反)。だから何でも標準によって許可されています。'ZERO'の場合と同じです。 – Olaf

答えて

4

IEEE 754はどのC標準でも要求されていないため、C11には混乱が生じるだけです。

IEEE374の32ビット浮動小数点数を仮定し、x2y2(無限大でもNaNでもない)以外の仮定をしないと、結果のビットがすべて0になるとは想定できませんIEEE 754の数値には2つのゼロがあり、1つは負と1つの正であり、式(y2 - y0) - (x2 - x0)が負の場合、ゼロを乗算した結果は負のゼロになります。

我々は、この短い例でそれをテストすることができます。

#include <stdio.h> 
#include <stdint.h> 

int 
main(int argc, char **argv) 
{ 
    union { 
     float f; 
     uint32_t i; 
    } foo; 

    float a = 0; 
    float b = -1; 

    foo.f = a * b; 
    printf("0x%x\n", foo.i); 

    return 0; 
} 

結果(私は、コンパイラは賢いことにしたくないので、何の最適化を気づかない):

$ cc -o foo foo.c && ./foo 
0x80000000 

ああ、ちょうど私あなたが「言い換えれば」と呼んだ質問の第2の部分は、別の質問であるため実際には別の言葉ではないことに気づいた。で開始する

(*(uint32_t*)(&a) == *(uint32_t*)(&b)) 

-0 == 0ので、浮動小数点ためa == bと同等ではありません。そして、それで、-0 - 0があなたに-0を与えるので、仮定のもう片方が崩壊します。私は等しい数の他の減算で負のゼロを生成することはできませんが、それは不可能ではありません、私は標準がすべての実装で減算のための同じアルゴリズムを強制しないことを確信していますサインビットが何とかそこに潜入する可能性があります。

+0

「負のゼロ」のものが良いキャッチです。私は実際に答えがはい(あなたのことを読む前に)であると思います。 –

+0

ありがとう、アート!もちろん、IEEE標準の記載は少し誤解を招くことは言うまでもない。私が最も興味を持っているのは、一般的なハードウェア、一般的なC11コンパイラ、またはチェックをスキップして安全に行うことができるかどうかを確認することです。署名付きゼロコメントは非常に役に立ちます!私は 'ゼロビットパターン'ゼロの代わりに0にFP比較を行うことで大丈夫だろう。それは安全でしょうか? – MrMobster

+0

@MrMobster浮動小数点数をゼロに比較する最も安全な方法は 'a == 0.0'です。これは、aが負であるか正であるかに関係なく機能します。 – Art

関連する問題