Google spreadsheetの計算精度について
こんにち、一般に浮動小数点数はIEEE754 binary64
の形式に準拠している。 この規格では、十進小数を15.95桁の精度で表現する。 ゆえに、たとえば、0.1+0.2
と0.3
は等しくない
Google spreadsheetやMS-Excelもこの例に漏れていない。 ただし、これらの表計算ソフトは一部の計算において、その精度を十進小数15桁に落としている。 ゆえに、たとえば、=(1+1E-15) = 1
は=true
となる。 したがって、"IEEE754 binary64
に準拠した計算"が困難となる。
このことは、ダメージ検証に際して大きな障害であった。 ダメージ検証では、数学分野や金勘定システムとは異なり、IEEE754 binary64
に準拠した十進小数15.95桁精度の計算が"正しい"。 特に、四則演算の順序や小数から整数への丸めにおいて、実際の挙動とは異なる計算結果を示していた。 よって、"正しい"計算を行うためにGoogle spreadsheetでIEEE754 binary64
に準拠した計算を行うことが求められた。 (Google spreadsheetを利用すべきなのかという疑問に対する回答は省略する。)導入は以上だ。結論を示す。
Google spreadsheetでIEEE754 binary64
に準拠した計算は可能だ(ほんまか?)。
例えば切り捨ての計算はこのように行う。まず、sign(・)で符号ビットを検証する。
ああ、いや、これは冗談だ。勘弁してくれ。いったい誰がこれを扱えるのか。私には無理だ。
私は以下のように行う。
a=b
はdelta(a,b)
を使う。a<>b
はnot(delta(a,b))
を使う。a<=b
はgestep(a,b)
を使う。a>b
はnot(gestep(a,b))
を使う。- 四則演算
+
、-
、*
、-
はそのまま使える。 int(a)
はint(a)-not(gestep(a,int(a)))
を使う。ceiling(a)
はceiling(x) + not(gestep(ceiling(x), x))
を使う。min(args)
およびmax(args)
はそのまま使える。- Google Apps Script (GAS) はそのまま使える。ただし、関数呼び出しが遅い。
int(a)-not(gestep(a,int(a)))
による切り捨ての実例を示す。
表計算ソフトで金勘定をするべきではない。