典型的な現代のプロセッサーおよびプログラミング言語は、float
の32ビット2進浮動小数点数とdouble
の64ビット2進浮動小数点数を使用してIEEE-754算術演算を使用します。 double
には、53ビットの仮数が使用されます。これは、10進数がdouble
に変換されるとき、それはいくつかの数S•2 F ESは符号である、(+1又は-1)•、に変換される、ということを意味しますfは53ビットで表現できる符号なし整数で、eは-1074〜971の整数です。 (変換される数値が大きすぎる場合、結果は無限大または無限大になる可能性があります)。浮動小数点形式を知っている人は、指数が-1023から1023までの間で適切だと不平を言うかもしれませんが、数値を数値に変換して符号化するのではなく、数値を記述しています)。
変換する1からdouble
は3602879701896397/36028797018963968となります。これは、必要な形式のすべての数値のうち、最も近い数値です。 1。分母は2 -55なので、eは-55です。
これらのうちの2つを追加すると、7205759403792794/36028797018963968となります。分子はまだ2 より小さく、フォーマットに合っています。
3番目の3602879701896397/36028797018963968を追加すると、数学的結果は10808639105689191/36028797018963968になります。残念ながら分子は大きすぎます。 2 (9007199254740992)より大きい。したがって、浮動小数点ハードウェアはその数を返すことはできません。それは何とかフィットさせる必要があります。
分母と分母を2で割った場合、5404319552844595.5/18014398509481984です。これは同じ値ですが、分子は整数ではありません。それを適合させるために、ハードウェアは整数に丸めます。端数がちょうど1/2の場合、ルールは丸めて結果を偶数にするので、ハードウェアは5404319552844596/18014398509481984を返します。
次に、現在の合計5404319552844596/18014398509481984をとり、3602879701896397/36028797018963968を再度追加します。合計値がこの場合7205759403792794.5/18014398509481984.である。この時間は、ハードウェアが7205759403792794/18014398509481984.
を返し、切り捨てその後、我々は18014398509481984分の7205759403792794と36028797018963968分の3602879701896397を追加し、合計があること9007199254740992.5/18014398509481984.注意です分子は分数を有するだけでなく、2 より大きい。分子量を整数に丸めると、4503599627370496/9007199254740992が生成されます。
これはちょうど1/2です。この時点で、丸め誤差は偶然にキャンセルされました。 .1を5回追加すると正確に0.5になります。
我々は9007199254740992分の4503599627370496と36028797018963968分の3602879701896397を追加すると、結果が正確に5404319552844595.25/9007199254740992.ハードウェアは切り捨てと今では私たちは繰り返し切り捨てしようとしている見ることができます5404319552844595/9007199254740992.
を返しています。積算合計に3602879701896397/36028797018963968を加算するには、ハードウェアは分子を4で除算して一致させる必要があります。つまり、端数部分は常に.25になり、切り捨てられます。したがって、次の4つの合計も切り捨てられます。我々は、分子が24ビットに収まらなければならないだけ少ない代わりdouble
のfloat
で
1以上である9007199254740992分の9007199254740991、で終わるので、2未満(16777216)でなければなりません。したがって、算術演算が行われる前でも123456789が大きすぎます。それは15432099•2 、として表現されなければならない123456792. 1を加算した正確な数学的結果は15432099.125•2 であり、整数にその仮数を丸め収率15432099•2 、そうあります変化なし。しかし、4を足した場合、結果は15432099.5•2 となり、その値は0•2 になります。