0.1 のような小数は、基数 2 ではきれいに表現できません。
10 進数の 0.1 を基数 2 で表現したいとしましょう。1/10 に等しいことがわかっています。基数 2 で 1 を 10 で割った結果は、100.000110011001100...
進数の繰り返しシーケンスを使用します。
したがって、10 進数では 0.1 のような数値をきれいに表現するのは実際には非常に簡単ですが、基数 2 では 10 分の 1 に基づく有理数を正確に表現することはできません。格納できるビット数を使用することによってのみ近似できます。
簡単にするために、その数値の最初の、たとえば 8 つの有効な 2 進数を再現するのに十分な記憶域しかないとしましょう。格納される数字は 11001100 (指数は 11) になります。これは、基数 2 で 0.000110011 に変換されます。これは、10 進数では 0.099609375 であり、0.1 ではありません。これは、0.1 を基本値を 8 ビット (符号ビットを含まない) で格納する理論上の浮動小数点変数に変換した場合に発生するエラーの量です。
浮動小数点変数が値を格納する方法
IEEE 754 の標準では、符号と 2 進指数を使用して、実数を 2 進でエンコードする方法が指定されています。指数はバイナリドメインで適用されます。つまり、バイナリに変換する前に小数点をシフトせず、後でシフトします。
IEEE 浮動小数点数にはさまざまなサイズがあり、それぞれが基数に使用される 2 進数の桁数と指数に使用される桁数を指定します。
が表示0.1 + 0.2 != 0.3
されているのは、実際には 0.1 または 0.2 に対して計算を実行しているのではなく、これらの数値を浮動小数点 2 進数で特定の精度に近似して計算しているためです。結果を 10 進数に戻すと、このエラーのため、結果は正確に 0.3 になりません。さらに、結果はバイナリ近似の 0.3 にも等しくなりません。エラーの実際の量は、浮動小数点値のサイズ、つまり使用された精度のビット数によって異なります。
丸めが役立つ場合もありますが、この場合はそうではありません
場合によっては、2 進数への変換での桁落ちによる計算エラーは、2 進数からの再変換中に値が四捨五入されるほど小さいため、違いに気付くことさえありません。働きました。
IEEE 浮動小数点には、この丸めの実行方法に関する特定の規則があります。
ただし、0.1 + 0.2 対 0.3 では、丸めによってエラーが相殺されません。 0.1 と 0.2 の 2 進近似を加算した結果は、0.3 の 2 進近似とは異なります。