2016-09-09 9 views
4

浮動小数点数を比較する方法の問題has been answered here。この質問は、私が数式について質問している点で異なります。PHPの浮動小数点数を比較するための公式

if (abs(($a-$b)/$b) < $epsilon) { … } 

if (abs($a-$b) < $epsilon) { … } 

なぜ最初の答えは、除算を含まない2つの最高の投票答えが問題にわずかに異なる解決策がありますか?それは不正確な結果を引き起こしませんか?たとえば(簡単な数値を使用)、$ aと$ bの両方を0.01とし、$ a - $ bの結果は0.0001、$εの値は0.001と仮定します。

((((0.01 - 0.01) == 0.0001)/0.01 == 0.01) < 0.001) : false 

(((0.01 - 0.01) == 0.0001) < 0.001) : true 

のに対し、私の数学は少し錆びたかもしれませんが、私は何をしないのですか?

いつどちらの式を使用すればよいですか?

+1

@luweiqiない重複した、異なる質問。私は提案された複製をリンクさえしました。 – Twifty

+0

あなたの更新された質問がより明確になりました。私は近い投票を退けました。乾杯! – Panda

+0

関連:http://stackoverflow.com/q/328475/3990767 – SOFe

答えて

3

これはおそらく絶対エラーではなく相対エラーでイプシロンをチェックすることを可能にします。上記の例の値について

function areEqual(float $a, float $b) : bool { 
    return abs(($a - $b)/$b) < 0.00001; 
} 
areEqual(10000, 10000.01); 
areEqual(0.0000001, 0); 

ファクト:

は、これら2例の比較当社のイプシロンここで可能な最小イプシロンはとにかく、これらの値よりもはるかに小さい利便‐ため0.00001であるが、それでは、この事実を無視してみましょう。我々のアルゴリズムでは、$a$bはどちらも似ていると仮定しているため、$aで割るか$bで割るかは関係ありません。実際には、10000はそれよりもはるかに大きく(非常に大きな指数)、0.0000001ははるかに小さくすることはできますが、便宜上、これらが問題を引き起こす可能性のある値であるとしましょう。

ここでは既に違いを確認できます。

多数の場合:比較された浮動小数点が非常に大きい場合、εは小さすぎる可能性があります。浮動小数点数は内部的には精度のために一定の桁数しか格納できませんが、指数はそれよりも大きくなる可能性があります。その結果、浮動小数点誤差の原因、すなわち浮動小数点の最終桁は、単位桁よりも高い可能性があるどこかに現れる。言い換えれば、極端に大きな浮動小数点の場合、絶対誤差は1よりも大きく、0.00001のはるかに小さくなります。

小さな番号の場合:これはさらに明らかです。どちらの数字もイプシロンより小さい。たとえそれらを0と比較しても、相対誤差は無限大ですが、あなたはまだそれらが等しいと考えます。この場合、両方のオペランドを乗算するか、イプシロンを減らします。実際には同じですが、実装に関しては、小数(/ 0.0001* 10000と等価)に掛け算されるオペランドの1つを除算するか、または大数の場合は除算すると便利です(/ 10000差はおそらく10000より小さくなります)

このチェックの別の名前があります。 abs($a - $b)は絶対誤差と呼ばれますが、通常相対誤差を使用します。絶対誤差は÷近似値です。値も負の値になる可能性があるので、代わりにのabsを全部返します。この場合の私たちの "イプシロン" 0.00001は、私たちの許容相対誤差が0.00001、すなわち0.001%誤差であることを意味します。


これは であり、まだではありません。絶対に安全ではありません。あなたのプログラムで数多くの変換が行われた後は、数値をいくつかの大きな数値で追加/掛けた後、再び減算して、人間にとっては無視できる程度の大きな数値に不純な誤差を残します。したがって、イプシロン値または浮動小数点比較アルゴリズムを選択する前に、常に2度考えてください。

大きな数値を小さな数値で加算、減算、または乗算することは避けてください。エラーが発生する可能性が高くなります。あなたのアルゴリズムを開発する(特に単純化する)際には、常に浮動小数点にエラーがあるかもしれないことを考慮してください。これは仕事の負荷を馬鹿げた程度まで増加させるかもしれませんが、あなたがそれを認識している限り、このような心配は時々あなたがチームから追い出されるのを防ぎます。

+0

最後の段落は家に帰った。私は単純なGPS座標比較をしていますが、私はそれらを生成するために使用するアルゴリズムのいくつかについて忘れていました。私の場合は、最終結果がお互いに数メートル以内であることだけに気をつけているので、絶対的なエラーを使うだけで十分だと思います。しかし、将来のために心に留めておくべきこと。 – Twifty

+0

@Twiftyありがとうございます。それが役に立つと思ったら答えを受け入れてください。 – SOFe

0

精度と精度の問題です。あなたが部門をやっていなければ、あなたは正確さを見ているので、あなたの基準を知っていて、小数点第n位(またはあなたが選んだもの)には良いことは十分です。あなたが部門を行う場合、正確さを話​​している(エラー率を考える)ので、あなたが金のイヤリングを販売している場合、オンスから離れていることはひどいです。

0

浮動小数点数が指数を持つという事実を考慮するには、除算があります。これは、数値自体が大きくなると、連続する2つの数値の最小の差が大きくなることを意味します。例えば

1e-3002e-300は、2つの異なる数値(IEE 754 64ビットタイプの)であるが、1e3001e300 + 1e-300は同じです。

関連する問題