私は現在Javaで浮動小数点数を比較しています。最も簡単な式は次のとおりです。
Math.abs(a - b) < THRESHOLD
差異のしきい値として変数に名前を付ける場合、デルタまたはイプシロンのどちらに名前を付ける必要がありますか?具体的には、浮動小数点数が表すことができる最小値の正しい項はどれですか。
プログラミング言語という用語は特定のものですか、それとも言語間で共通ですか?
私は現在Javaで浮動小数点数を比較しています。最も簡単な式は次のとおりです。
Math.abs(a - b) < THRESHOLD
差異のしきい値として変数に名前を付ける場合、デルタまたはイプシロンのどちらに名前を付ける必要がありますか?具体的には、浮動小数点数が表すことができる最小値の正しい項はどれですか。
プログラミング言語という用語は特定のものですか、それとも言語間で共通ですか?
回答:
数学と工学のイプシロン
数学と工学一般では:
そしてイプシロンはあなたの場合により適切であるようです。
コンピュータサイエンスのイプシロン
特にコンピュータサイエンスでは、イプシロンという用語は、と厳密に大きい最小のフロートとの差を測定するマシンエスピロンも指します。後者の数値はJavaのフロート用であり、次のように計算できます。1.0f
1.0f
1.00000011920928955078125f
float f = Float.intBitsToFloat(Float.floatToIntBits(1f) + 1);
マシンのイプシロンの定義は、上記のイプシロンの一般的な使用と一致しています。
フロートの比較
ただし、フロートの「近接性」を比較する前に、フロートの規模を把握しておく必要があります。2つの非常に大きく、おそらく非常に異なるフロートは等しい場合があります。
9223372036854775808f == 9223372036854775808f + 1000000000f; //this is true!
そして逆に、マシンのイプシロンのみが異なる2つの小さなフロートの間には、多くの可能なフロート値(および数桁)がある可能性があります。以下の例では、small
との間に10,000,000の使用可能なfloat値がありますf
が、それらの差はまだマシンイプシロンをはるかに下回っています。
float small = Float.MIN_VALUE; // small = 1.4E-45
float f = Float.intBitsToFloat(Float.floatToIntBits(small) + 100000000); // f = 2.3122343E-35
boolean b = (f - small < 0.00000011920928955078125f); //true!
GlenH7の回答にリンクされた記事は、フロートの比較をさらに調査し、これらの問題を克服するためのいくつかのソリューションを提案しています。
数学では、デルタは値との差を表すために使用され、イプシロンは任意のエラー値を表すために使用されます。この場合、イプシロンが従来の名前になります。
質問に直接答えるには、用語を使用しepsilon
ます。より正確には、それはmachine epsilon
一般的使用法は「機械」を落とし、ただ使用するだけepsilon
です。
私のローカルコピーを見ると、次のfloat.h
ことがわかります。
#define DBL_EPSILON 2.2204460492503131e-016 /* smallest such that 1.0+DBL_EPSILON != 1.0 */
#define FLT_EPSILON 1.192092896e-07F /* smallest such that 1.0+FLT_EPSILON != 1.0 */
#define LDBL_EPSILON DBL_EPSILON /* smallest such that 1.0+LDBL_EPSILON != 1.0 */
そして関連するコメントは、イプシロンがあなたが言及している用語であることを明確にします。
しかし、それがepsilon
正しい用語であることを確認するために、他の外部参照に依存することもできます。ここ、ここ、ここ、そして最後に、SOクエリタグのこの組み合わせを参照してください。引用するIEEE 754標準への直接参照を見つけることができませんでした。
見てい浮動小数点値を比較した上で、弁のブルース・ドーソン、このブログの記事あなたが提案していることの比較を使用したくない理由として、いくつかの洞察力のために。
その記事にはかなりの情報が詰め込まれていますが、これはそこからの最も関連性の高い抜粋です。
フロートが等しいかどうかを比較することが悪い考えである場合、それらの違いが次のように、エラー範囲またはイプシロン値内にあるかどうかを確認するのはどうでしょうか。
bool isEqual = fabs(f1 – f2) <= epsilon;
この計算により、2つのフロートが等しいと見なすのに十分近い2つのフロートの概念を表すことができます。しかし、イプシロンにはどのような値を使用する必要がありますか?
上記の実験を考えると、合計で1.19e-7fの誤差を使用したくなるかもしれません。実際、float.hにはその正確な値の定義さえあり、FLT_EPSILONと呼ばれています。
明らかにそれだけです。ヘッダーファイルの神々が話しており、FLT_EPSILONは1つの真のイプシロンです!
それがゴミだということを除いて。1.0〜2.0の数値の場合、FLT_EPSILONは隣接するフロート間の差を表します。1.0より小さい数値の場合、FLT_EPSILONのイプシロンはすぐに大きくなりすぎます。十分に小さい数値では、FLT_EPSILONは比較している数値よりも大きくなる可能性があります。
ドーソンは、浮動小数点数を比較し、このような非常に小さな値を処理する際の複雑さに関する他の多くの考慮事項を検討しているので、彼の投稿の残りを読むことをお勧めします。
私はそれを「寛容」と呼んでいます。
多分それは数学的に正しい用語ではないかもしれませんが、あなたが質問をするという単なる事実は、「デルタ」も「イプシロン」も使用するのに適した変数名ではないことを意味します。
私の経験では、実際にコードを読む人にとって意味のある識別子名を使用することをお勧めします。それが意味を理解するために読者がウィキペディアでそれを調べなければならないということを意味するならば、完全に正しい名前は何が良いのでしょうか?