こことここを参照...イプシロン法ではなく 2 の補数を使用するのはなぜですか? ほとんどの場合、イプシロン法で十分なようです。
更新: 私は純粋に、どちらか一方を使用する理論的な理由を探しています。私はいつもイプシロン法を使ってきました。
2 の補数比較を成功させた人はいますか? なんで?なぜだめですか?
あなたが参照する2番目のリンクは、問題の非常に長い説明を持つ記事に言及しています:
http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
しかし、パフォーマンスを微調整しない限り、人々があなたのコードをデバッグできるように、私はイプシロンに固執します
つまり、起源が不明な 2 つの float を比較する場合、有効なイプシロンを選択することはほとんど不可能です。
例えば:
ジョージア州アトランタ、テキサス州ダラス、オハイオ州のどこかの間の距離をマイルで比較する場合、適切なイプシロンはどれですか?
左足、右足、および机の下にあるコンピューターの間の距離をマイル単位で比較する場合、適切なイプシロンはどれくらいですか?
編集:
わかりました、かなりの数の人が、自分のイプシロンが何であるかを知らない理由を理解していません.
昔の伝承の時代に、NeverWinter Nights (BioWare 製のゲーム) で動作する 2 つのプログラムを書きました。プログラムの 1 つがバイナリ モデルを取得し、それを ASCII に変換しました。もう 1 つのプログラムは ASCII モデルを取得し、それをバイナリにコンパイルしました。私が作成したテストの 1 つは、BioWare のすべてのバイナリ モデルを取得し、それらを ASCII に逆コンパイルしてからバイナリに戻すというものでした。次に、自分のバイナリ バージョンと BioWare の元のバージョンを比較しました。比較中の問題の 1 つは、浮動小数点値のわずかな差異を処理することでした。したがって、浮動小数点数のタイプ (頂点、法線など) ごとにさまざまな EPSILON を考え出す代わりに、この 2 の補数比較のようなものを使用したいと考えました。したがって、複数の EPSILON 問題全体を回避します。
同じタイプの問題は、サードパーティのデータを処理し、その結果を元のデータで検証する必要があるあらゆる種類のソフトウェアに適用できます。このような場合、浮動小数点値が何を表しているかさえわからないかもしれません。それらを比較するだけです。この問題は、当社の産業オートメーション ソフトウェアで発生しました。
編集:
LOL、これはさまざまな人々によって賛成票と反対票を投じられました。
問題を要約すると、2 つの任意の浮動小数点数が与えられた場合、どのイプシロンを使用するかをどのように決定するのでしょうか? できません。
1e23 と 1.0001e23 をイプシロンと比較し、同じイプシロンを使用して 1e-23 と 5.2e-23 を比較するにはどうすればよいでしょうか? 確かに、いくつかの動的なイプシロン トリックを実行できますが、それが整数比較の要点です (整数が正確である必要はありません)。
整数の比較では、数値の大きさに対するイプシロンを使用して 2 つの浮動小数点数を比較できます。
編集
スティーブ、コメントであなたが言ったことを見てみましょう:
「しかし、あなたは平等があなたにとって何を意味するかを知っています...したがって、適切なイプシロンを見つけることができるはずです」.
このステートメントをひっくり返して、次のように言います。
「あなたにとって平等が何を意味するかを知っていれば、適切なイプシロンを見つけることができるはずです。」
私が言おうとしていることの要点は、絶対的な意味での等値の意味がわからないアプリケーションがあるため、整数バージョンが行おうとしている相対的な比較に頼らなければならないということです。
ビット方式の方が速いかもしれません。最新の (マルチコアで高度にパイプライン化された) プロセッサでは、実際に何が高速かを推測することがしばしば不可能なためです。最も単純で最も明らかに正しい実装をコーディングし、次に測定し、次に最適化します。
速度に関しては、次のルールに従ってください。
最も簡単な方法を実行します。
アレックス
オスカーの権利。あなたが本当に本当にそのパフォーマンスを必要としない限り、これを台無しにしないでください。
そして、あなたはしません。もしあなたがそうする状況にあったなら、あなたは質問をする必要はなかっただろう-あなたはすでに知っているだろう。あなたがそう思うなら、あなたはそうしません。パフォーマンスの問題は他の場所にあります。読み取り可能なバージョンを使用してください。
ビット単位で比較する方法を使用すると、分数が近似で表されるときに問題が発生します。2の累乗(1 / 2、1 / 4、1 / 8、1 / 65536、&c)で表されない分数を持つすべての浮動小数点数が概算されます。したがって、もちろん、すべての無理数です。
フロートサード=1/3; float two = 2.0; float another_two = third * 6.0; if(two!= another_two)print( "近似!\ n");
ビット単位で比較する場合にのみ機能するのは、浮動小数点数をまったく同じ方法で導出するか、正確な表現(整数、2の小数乗)である場合のみです。それでも、実際のシステムではこれを見たことがありませんが、いくつかの数値の複数の表現が存在する可能性があります。