Pythonプログラミングイントロダクション(3章) 浮動小数点の誤差はなぜ発生する?

2019–10–20

3章は算術プログラムの章です。近似について学べます。 全順序について述べられていたりする点、さすがアカデミックだなぁと思いつつ読み進めました。

近似に関しては2文法とニュートンラフソン法が示されています。 2分法は名前から想像しやすいですが、2分探索のようにあり得る値の中間値の計算結果の大小から推定値を移動させていく手法です。 ニュートンラフソン法は初耳でした。

また浮動小数点の説明が非常にわかりやすかったです。実際の計算結果からずれることがある、くらいの理解だったのですが、2進数の都合上なぜ、どのようにずれるかが説明してあって納得でした。

浮動小数点とは

小数を浮動小数点を用いて表現するとは、仮数、基数、指数を用いて表現することになります。 名前の通り小数点の位置が固定ではないことから浮動小数点と言います。

例えば 5/8の場合は、下記のようになります。

\[\frac{5}{8} = 5 * 2^{-3}\]

この場合,仮数は5, 基数は2, 指数は3になります。この場合は誤差は出ないです。そしてコンピュータは2進数で値を表現するので、基数は2となります。

しかし1/10の場合は誤差がどうしても出てしまいます。 下記は1/10を指数部を5,6,7と増やしていった場合の実際の値です。

\[3 * 2^{-5} = 0.9375\]

\[6 * 2^{-6} = 0.9375\]

\[12 * 2^{-7} = 0.9375\]

\[25 * 2^{-8} = 0.9765625\]

このようにいくら指数部の値を増やして行っても0.1にはたどり着けません。 浮動小数点では値によってどうしても誤差が出てしまうわけです。

0.1が実際どのような値となっているかは下記のようにして見ることができます。

print( format(0.1, '.55f') )	  

値は0.1000000000000000055511151231257827021181583404541015625となります。

まとめ

3章の中から特に浮動小数点に関して取り上げました。 金額を計算するときとか、気を付けろぐらいにしか意識していなかった浮動小数点ですが、整理できてよかったです。