数値型の計算誤差
AliceScriptの数値型は、倍精度浮動小数点数数値型と定められており、この規格はIEEE754として標準化されています。 しかしこの数値型で小数の計算をしているとき、その計算結果が期待通りでないことがあります。この記事では、その理由について説明します。
計算誤差の例
0.1 + 0.2 == 0.3
数学では、上記の式は正しくtrue
と評価されますし、ほとんどの開発者も、それが正しいことを期待します。
では、AliceScriptでこの式を評価してみます。
print(0.1 + 0.2 == 0.3);
このコードを実行すると、false
が出力されます。
理由
これらの計算誤差はバグではありません。AliceScriptの数値型のような浮動小数点数数値型は、値を2進数で格納していますが、ほとんどの10進数の小数は2進数で表すことができず、その近似値として表現されます。近似値の誤差が例に示したような計算誤差として現れます。
知的好奇心旺盛なあなたのために、もう少し説明します。例えば10進数の0.1
を2進数に変換すると0.0001100110011…
となり、0011
が永遠と循環します。そのため0.1
を倍精度浮動小数点数数値型に格納するには、適当な桁で丸める必要があります。このとき、最も近い偶数に値を丸めます。その結果として0.1
は数値型では2進数で0.0001100110011001100110011001100110011001100110011001101
となります。これを10進数に戻す0.1000000000000000055511151231257827021181583404541015625
となり、0.1
ではなくなります。
ただし整数は、有効桁数15桁の範囲内であれば、正確に格納できます。また小数であっても、k/(2^n)(kとnは整数)
で表すこともできる小数は2進数で表現できるため、正確に格納できます。
なおこのような誤差は、AliceScript固有のものではありません。IEEE 754の2進浮動小数点形式を採用しているシステムでは、同じことが起こりえます。