これはPHPに限った問題ではないが、コンピュータ・プログラムは内部で2進数演算しているため、 10進数の計算と比べると誤差が発生することがある。そこで今回は、演算誤差の具体事例と対策を考えていく。
演算誤差
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行目)、演算誤差はないといえる。
ところが、単純な乗算プログラムなのに演算誤差が発生するケースがある。19行目がそれである。
期待する結果は 702100 であるはずなのに、702099 と表示されてしまう。
だが、奇妙なことに、printf 関数の %f 修飾子(小数表示)を利用すると、702100.000000 と表示される。
整数化の際に誤差が発生しているのだ。
| 2006年12月09日更新 | ||
| <<前へ | <目次> | 次へ>> |
| 戻る | 【関連ページ】 | |