#まえがき
丸め誤差について気を付けることをまとめる。
#何が問題になるのか
以下のコードを見てください。
s = 0
for i in range(1000):
s += 0.001
print(s) # 1.0000000000000007
0.001を1000回足したら1になるはずですが、謎の小数点以下の誤差が生じました。
これは、丸め誤差というものです。
#丸め誤差とは?
人間は十進数を共通の数字として用いていますが、計算機は二進法を用いて計算を行います。
(ちなみに進数法を表記するときは「10進数」ではなく「十進数」と書きましょう)
二進数の変換は、
1は1
2は10
4は100
といったように、整数の範囲では簡単ですね。
小数点以下を表すときが厄介です。
0.5は0.1
0.25は0.01
0.125は0.001
そして0.001は
0.000000000100000110001001001101110100101111000110101001111111...
▂▅▇█▓▒░(’ω’)░▒▓█▇▅▂うわあああああ
(1/2)^nを組み合わせて表現できない小数は際限なく続いてしまいます。
このような小数を扱うときは桁が途中で丸められてしまい、計算に誤差が生じるわけです。
#やってはいけない例
この誤差がどう問題になるのか。それは、==
で比較できなくなるということです。
s = 0
while(True):
if(s == 1):
break
s += 0.1
# 終わらない
10回足せばbreakで終わりのはずが、永遠に計算し続けます。
これを回避するためには、誤差を設定してあげます。
s = 0
eps = 1e-10 # 十分に小さい正の誤差を設定する。
while(True):
if(abs(s - 1) < eps): # 1との差が誤差の範囲で収まっているか
break
s += 0.1
print(s) # 0.9999999999999999
#まとめ
小数を扱うときは完全一致で比較しないこと。以上。
『機械学習のエッセンス』という本を参考にしました。しばらくこの本について勉強したことをまとめていきます。
次回:桁落ちに気をつけよう
https://qiita.com/NNNiNiNNN/items/af550e9f1c72aadd2577