FPU 10 進文字列の小数部が等しいかどうかを比較しない
問題は、float 値または double 値と小数を含む 10 進定数との等価比較がほとんど成功しないことです。
2 進数の FP 表現で正確な値を持つ 10 進文字列の分数はほとんどないため、通常、等値比較は失敗に終わります。*
あなたの正確な質問に答えるために、これ2
は 10 進文字列分数の形式へのわずかに異なる変換から来ていFloat
ます。分数を正確に表すことができないため、2 つの計算が中間計算で異なる量の精度を考慮し、最終的に結果を 52 ビットの IEEE 754 倍精度仮数に異なる方法で丸める可能性があります。とにかく正確な表現がないため、ほとんど問題ではありませんが、おそらく一方が他方よりも間違っている可能性があります。
特に、1876.8
FP オブジェクトで正確に表現することはできません。実際には、0.01 から 0.99 の間で、0.25、0.50、および 0.75 だけが正確なバイナリ表現を持っています。1876.8 を含む他のすべては、永久に繰り返され、52 ビットに丸められます。これは、BigDecimal が存在する理由の約半分です。(理由の残りの半分は、FP データの精度が固定されているためです。場合によっては、それ以上の精度が必要になります。)
したがって、実際のマシン値を 10 進文字列定数と比較したときに得られる結果は、2 進小数部のすべてのビットに依存します... 1/2 52まで... さらに丸めが必要です。
数を生成するプロセス、入力変換コード、またはその他の関連する部分に、ほんの少しでも (へへ、少し、申し訳ありませんが) 不完全なものがある場合、それらは完全に同じには見えません。
IEEE 形式の FPU はその数値を正確に表すことさえできないため、比較は常に失敗するはずであるという議論がなされることさえあります。同じように見えても、実際には同じではありません。左側では、10 進数の文字列が 2 進数の文字列に変換されていますが、ほとんどの数値は正確に変換されていません。右側は、まだ 10 進文字列です。
したがって、フロートと BigDecimal を混在させないでください。1 つの BigDecimal と別の BigDecimal を比較してください。(両方のオペランドが浮動小数点数の場合でも、等しいかどうかのテストには細心の注意またはファジー テストが必要です。また、すべてのフォーマットされた数字を信頼しないでください。出力フォーマットでは、分数の右側から余りが繰り出されるため、通常は開始しません。ゼロを見ると、ガベージ値が表示されます。)
*問題: 機械数は x/2 nですが、10 進定数は x/(2 n * 5 m ) です。符号、指数、および仮数としての値は、0 10000001001 1101010100110011001100110011001100110011001100110011...
皮肉なことに無限に繰り返されます。FP 演算は完全に正確であり、値に端数がない場合、等値比較は完全に機能します。