(注:ここでは2進数を示すために「b」を追加します。他のすべての数値は10進数で示されます)
物事を考える1つの方法は、科学表記法のようなものです。私たちは、6.022141 * 10 ^ 23のような科学表記法で表された数値を見るのに慣れています。浮動小数点数は、仮数と指数の類似の形式を使用して内部的に格納されますが、10の代わりに2のべき乗を使用します。
61.0は、仮数と指数を使用して1.90625 * 2 ^ 5または1.11101b * 2 ^ 101bに書き換えることができます。これに10を掛けて(小数点を移動)するには、次のようにします。
(1.90625 * 2 ^ 5)*(1.25 * 2 ^ 3)=(2.3828125 * 2 ^ 8)=(1.19140625 * 2 ^ 9)
またはバイナリの仮数と指数と一緒に:
(1.11101b * 2 ^ 101b)*(1.01b * 2 ^ 11b)=(10.0110001b * 2 ^ 1000b)=(1.00110001b * 2 ^ 1001b)
数値を乗算するためにここで行ったことに注意してください。仮数を乗算し、指数を追加しました。次に、仮数部が2より大きく終わったので、指数をバンプして結果を正規化しました。これは、10進数の科学表記で数値の演算を実行した後に指数を調整する場合と同じです。どちらの場合も、使用した値はバイナリで有限表現されていたため、基本的な乗算および加算演算によって出力された値も有限表現の値を生成しました。
ここで、61を10で除算する方法を考えてみましょう。まず、仮数1.90625と1.25を除算します。10進数では、これは1.525といい、短い数字です。しかし、バイナリに変換するとどうなるでしょうか。通常の方法で行います。整数の10進数を2進数に変換するのと同じように、可能な限り最大の2の累乗を差し引きますが、2の負の累乗を使用します。
1.525-1 * 2 ^ 0-> 1
0.525-1 * 2 ^ -1-> 1
0.025-0 * 2 ^ -2-> 0
0.025-0 * 2 ^ -3-> 0
0.025-0 * 2 ^ -4-> 0
0.025-0 * 2 ^ -5-> 0
0.025-1 * 2 ^ -6-> 1
0.009375-1 * 2 ^ -7-> 1
0.0015625-0 * 2 ^ -8-> 0
0.0015625-0 * 2 ^ -9-> 0
0.0015625-1 * 2 ^ -10-> 1
0.0005859375-1 * 2 ^ -11-> 1
0.00009765625 ...
ええとああ。今、私たちは困っています。1.90625 / 1.25 = 1.525は、2進数で表現すると繰り返し分数であることがわかります。そして、特定のポイントを超えてゼロを仮定します。61を10で割ったときに表示されるエラーは、次の違いです。
1.100001100110011001100110011001100110011 ... b * 2 ^ 10b
そして、例えば:
1.100001100110011001100100110b * 2 ^ 10b
浮動小数点値に関連する精度の損失につながるのは、仮数のこの丸めです。仮数が正確に表現できる場合でも(たとえば、2つの数値を加算するだけの場合)、仮数が桁数が多すぎて指数を正規化した後に収まらない場合は、数値が失われる可能性があります。
10進数を扱いやすいサイズに丸め、最初の数桁だけを指定するときは、常にこのようなことをしています。結果を10進数で表現するので、自然に感じます。しかし、小数を四捨五入してから別の基数に変換すると、浮動小数点の四捨五入により、小数と同じくらい醜く見えます。