数値解析日記

数値解析関係のネタ帳。C++,pythonなど

メモ:twosumアルゴリズムの研究

twosumアルゴリズムの研究

from pint import roundfloat as rf
from pint import roundmode as rdm
a=0.1
b=0.2

誤差が発生するパターン

rf.rdadd(a, b, rdm.nearest)
0.30000000000000004

最近点丸め

rf.rdadd(a, b, rdm.up)
0.30000000000000004

上方向丸め。最近点丸めと一緒なので、最近点丸めでは上方向に丸め込まれた

rf.rdadd(a, b, rdm.down)
0.3

下方向丸め。最近点丸めと別方向に曲がったことがわかる

rf.twosum(a, b)
(0.30000000000000004, -2.7755575615628914e-17)

twosumを実行してみると、最近点丸めの際の、真値(2進数表現できない)との誤差の方向が検出できているのがわかる。
詳しく見ていこう

x = a + b
print(x)
0.30000000000000004

普通の足し算だ

tmp = x - b
print(tmp)
0.10000000000000003

tmp = x - b = (a + b) - b = a であるのでこれはaとなるはずである。
だが、ならない
xは最近点丸めで計算されているため、bを引き算したときに、aに誤差sが加算されている。
tmp = a + 誤差s という形になっている

y = a - tmp
print(y)
-2.7755575615628914e-17

y = a - tmp = a - (a + 誤差s) = 誤差s という式になっている