PHP等での丸め誤差floor()round()...を使うときの注意

はじめまして、skmtです。
自分なりの適当な技術録などを書き溜めていこうと思うので参考になれば幸いです。
   * 自分はほとんどGoogle先生に聞いて検証しての記事なのでほぼほぼここにたどり着いて合点を得ることはないでしょうw


今回自分に降りかかったの問題。
PHPで金額の細かい計算をさせていたところ、どうも数値が合わないぞと。
1円合わないぞと。電卓で打って金額が割り切れているのになんでやとなったので、調べたわけでその結果をば。



まず環境、Windows.PHPでは元よりBCMathの精度関数が使えるので気にせず、それ以外のパッケージでは別途インストールが必要。


浮動小数型を経て結果が整数値となった等でも切り捨てのfloor()やround()等の四捨五入・切捨て関数では1の誤差が出ます。

なのでBCMathの精度数学関数を使って計算したあとfloor()等を使ってやればよいと。
 * BCMathの返り値はdecimal等ではなくStringです。

なぜ誤差が出るのかというのはコンピューターが何進数で動いているものなのかを考えれば理解いただけると思います。

マニュアルからぶっこ抜いてきたのを

<?php
echo bcmul('1.34747474747', '35', 3); // 47.161
echo bcmul('2', '4'); // 8
?>

こんな感じで?
第3引数は小数点以下第何位かなので有効桁数とお間違えないよう。