数値計算
はじめに
実計算に誤差はつきものである。 誤差にはいくつか種類があり、それは計算機に特有のものもあれば、そうでないものもある。 まず背景知識として、計算機での数値表現を説明する。 その後、数種類の誤差を紹介し、それぞれの例と対策を簡単に考える。 最後に誤差対策に使えそうな手法をいくつか紹介する。
計算機上での数値表現
int 型
http://www.kab-studio.biz/Programing/JavaA2Z/Word/00000249.html
固定小数点
http://www.kab-studio.biz/Programing/JavaA2Z/Word/00000148.html
float 型
https://www.cc.kyoto-su.ac.jp/~yamada/programming/float.html
http://www.kab-studio.biz/Programing/JavaA2Z/Word/00000097.html https://itmanabi.com/fixed-floating/
参考
http://www.kab-studio.biz/Programing/JavaA2Z/List/index.html
そもそもの誤差
測定誤差
例) 最小メモリが 1mm の定規 https://kotobank.jp/word/%E6%B8%AC%E5%AE%9A%E8%AA%A4%E5%B7%AE-1181095 https://www.keyence.co.jp/ss/measure/hakaritai/basic/errors/
有効数字も参考のこと http://dsl4.eee.u-ryukyu.ac.jp/DOCS/error/node6.html
離散化による誤差
音をデジタル化するときなどに発生する
http://www.mb.ccnw.ne.jp/kontoshi/papa/gimon/oto.htm http://www.kumikomi.net/archives/2010/07/ep22onse.php
float による誤差
丸め誤差
真の値を取ることが出来ない。 1/2 の乗数は、真の値を取れる。
s = 0 v = 0.1 for i in range(10): s += v print(s) # 0.9999999 s = 0 v = 0.125 # 1/2 ** 3 for i in range(8): s += v print(s) # 0.9999999
http://www.kab-studio.biz/Programing/JavaA2Z/Word/00000521.html
情報落ち誤差
大きな数と小さな数の加算による誤差
big = 10 ** 15 + 0.1 print(big) # debug small = 0.1 ** 15 print(small) # debug v = big - small print(v) # debug if v == big: print(True) # こっちに入る else: print(False)
ALU は double より大きい bit 数で計算してたりするから、情報落ちしないこともある
//TODO 実際に試す tmp = big + small; res = tmp - big res == 0 // tmp という変数に起こすと情報落ちするけど res = big + small - big res == small // 変数に起こさなければ、ALU が大きな bit を扱ってる場合は、情報落ちしないことがある
桁落ち誤差
近い値を持つ数の減算
x = 0.99999 y = 0.99998 print('x') # debug print(x) # debug print('y') # debug print(y) # debug print('x - y') # debug print(x - y) # debug a = 0.9 b = 0.8 print('a') # debug print(a) # debug print('b') # debug print(b) # debug print('a - b') # debug print(a - b) # debug print('0.1') # debug print(0.1) # debug
その他の誤差
打ち切り誤差
漸化式を打ち切ることによる誤差 \sum 1/k2 = \pi ^2 / 6
その他の対策
分数 型 (有理数型) https://docs.python.org/ja/3/library/fractions.html
区間演算 https://ja.wikipedia.org/wiki/%E5%8C%BA%E9%96%93%E6%BC%94%E7%AE%97