PHPの演算誤差

(1/3)
PHP に限った問題ではないが、コンピュータ・プログラムは内部で 2進数演算しているため、10進数の計算と比べると誤差が発生することがある。そこで今回は、演算誤差の具体事例と対策を考えていく。

サンプル・プログラム

プログラムを実行する

ダウンロード(PHP4/5共用)

サンプル・プログラムの解説

0001: <?php
0002: /** marginerror.php
0003:  * PHPの演算誤差を確認する
0004:  * @copyright (c)studio pahoo
0005:  * @author     パパぱふぅ
0006:  * @version     1.0 2006/12/06
0007: */
0008: //循環小数
0009: $a = 1;
0010: $b = 3;
0011: $x = $a / $b;
0012: printf("%s÷%s=%f<br />\n", $a$b$x);
0013: $x = $x * $b;
0014: printf("%s÷%s×%s=%f<br />\n", $a$b$b$x);
0015: 
0016: //小数乗算
0017: $a = 10000;
0018: $b = 70.21;
0019: $x = $a * $b;
0020: printf("%s×%s=%d<br />", $a$b$x);
0021: printf("%s×%s=%f<br />", $a$b$x);
0022: ?> 

プログラムを実行すると、11行目の演算結果は 0.333333....(循環小数)となるため、結果は切り捨てになってしまう。これは表現上の問題なのでやむを得ない。商に 3 を乗算してやれば、1 に戻るので(13行目)、演算誤差はないといえる。
space
ところが、単純な乗算プログラムなのに演算誤差が発生するケースがある。19行目がそれである。期待する結果は 702100 であるはずなのに、702099 と表示されてしまう。
だが、奇妙なことに、printf 関数の %f 修飾子(小数表示)を利用すると、702100.000000 と表示される。
整数化の際に誤差が発生しているのだ。
この項つづく
header