#動機
前回の投稿で小数誤差について無知で理由やら対処法やら何やらしりたくなって調べます。
https://docs.python.jp/3/tutorial/floatingpoint.html
python3の公式チュートリアルを参考にしました。
#小数誤差の原因
原因は至って簡単でした。
プログラムは二進数で動いているので小数の計算は無限に続いていて、結局近似値の計算になるっていうことでした。
float
を使った場合は
どこか有限の桁で止めると、近似値を得ることになります。近年の殆どのコンピュータでは float 型は、分子に最も重大なビットから始めて最初の 53 ビットを使い、分母に 2 の累乗を使った、二進小数を使って近似されます。1/10 の場合は、二進小数は 3602879701896397 / 2 ** 55 となります。これは、1/10 に近いですが、厳密に同じ値ではありません。
と書いてあるとおり、結局は近似値なのです。
だから、前回の例を取るとx*1.08
とx*108/100
は結果が異なって当然だったというわけでした。
#小数誤差の対処法
先述の通り小数を使わずに割り算で記述すればいいだけです。
また、一応ちゃんとプログラムを書いて53ビットか確かめてみました。
print(2**53)
x = float(input())
z = x/39
print(z*39)
"""
9007199254740992
1.999999999999999 ひと桁少なくinput
1.999999999999999 結果
9007199254740992
1.999999999999999 同じ桁数でinput
2.0 結果
"""
というわけで、だいたい小数誤差についてはわかりました。
#おわりに
至らぬことが多く、ここにも間違った情報が書いてあるかもしれません。
間違った情報があればご指摘いただけると嬉しいです。
よりよいプログラムを書くためにがんばります!