つまり、.を保持する 32 ビット相当のメモリでは、すべての浮動小数点数 (すべての無限分散) を完全に表すことはできないということですfloat
。完全に表現できない数値のエラー値はごくわずかですが、存在します。
たとえば、1/3 は、最も近い float 表現で (おおよそ) 0.333333343267 です。10 進数で 7 桁の精度が得られると、少し問題が発生します。1 を 3 で割り、後で 3 を掛けたとします。結果は 1 ではなく、1.0000000298 となり、変化します。だから(1/3)*3 =/= 1
。
これらの表現上のエラーが、浮動小数点値を直接比較することが不適切な方法と見なされる理由です。
これらの小さなエラーの影響を最小限に抑える必要がある状況では、エラーが蓄積しないようにできる限りのことを行う必要があります。たとえば、一連の座標を少しずつ回転させると、不完全な結果が得られます。これは、各回転操作 (完全な float 表現を持つ可能性が低いsin
と のcos
値を使用) によって発生するエラーが時間の経過とともに蓄積されるためです。全体の角度変化を追跡し、元のベクトルを毎回回転させて、エラー値を小さくすることをお勧めします。
これがあなたを噛む可能性のある別の場所は、for
ループです。1ステップあたり1/30000で10,000ステップを実行したい場合は、ループ変数にintを使用し、現在位置を除算として計算します。はい、遅くなりますが、はるかに正確です。浮動小数点数を使用すると、毎回除算すると 7 桁を超えるのではなく、信頼できる 10 進数の有効桁数が約 3 桁になるまでエラーが蓄積されます。
速度は素晴らしいですが、状況によっては精度が優れています。
はい、ばかげているように見えますが、これらのエラーは実際に増加する可能性があります. それほど重要でない場所もあれば、エラー ファクトリが蔓延している場所もあります。