浮動小数点数は実数ではないため、別々の計算で生成された 2 つの浮動小数点数が正確に等しいと期待することの危険性について、すでに多くの質問と回答があります。この質問は、等価性チェックを条件とする正確性に関するものではなく、それに基づくキャッシュに関するものです。
次のコードがあるとします。
if(myfloat != _last_float) {
refresh_expensive_computation(myfloat);
_last_float = myfloat;
}
この場合、等値比較は、冗長な作業を避けるために純粋に存在します。入力が変更されていない場合、コストのかかる計算を再度実行することは避けています (コストのかかる関数は決定論的であり、他の入力が変更されていないと仮定します)。
2 つが実際には等しい (つまり、浮動小数点ではなく実数で計算できた場合に等しくなる) が、そうでないと誤って検出された場合、最悪の場合、高価な計算を重複して実行しますが、プログラムの答えは依然として正しいです。私の知る限り、float のメモリ表現よりも広いレジスタで計算が行われた場合 (たとえば、80 ビットの fp レジスタが有効な場合の 32 ビット x86)、メモリ表現に変換された後に、それらが誤って等しいと比較される可能性があります。両方がビットごとに等しくなるようにします。その場合、違いはメモリ表現の精度を超えている必要があります。これは、私にとって重要な比較のためにイプシロン未満でなければなりません。
したがって、この浮動小数点の等価性の使用は安全であると断言します。最初の質問は、私が間違っているのでしょうか?
第 2 に、安全であると仮定した場合、誤って true を返すことは避けたいと思います。これは、コストのかかる計算を引き起こすためです。メモリ表現よりも幅の広いレジスタを持つマシンでそれを回避する 1 つの方法は、 memcmp を使用して強制的にメモリ表現を比較することです (NaN のセマンティクスはまったく同じではありません。ただし、キャッシングの場合は改善されます。または、+0 と -0 の場合は特殊なケースになる可能性があります)。ただし、その memcmp は、レジスタでの浮動小数点比較よりも遅くなります。プラットフォームがより広いレジスタを持っていることを検出する方法はありますか?