はじめに
「PHP 小数 切り捨て」などと検索すると、
検索上位にfloor関数を使った小数点以下の切り捨てをする方法が紹介された記事が出てきます。
しかし、このfloor関数にはバグがあり、意図しない結果が返される場合があります。
本記事では、そのバグと対応策をご紹介します。
環境
- PHP 8.2.9
- Laravel Framework 10.24.0
バグ
floor関数には、浮動小数点の精度の問題があります。
例えば、
変数Aと変数Bを足した結果の小数第3位を切り捨てるのにfloor関数を使った場合、
変数Aと変数Bの値によっては意図しない結果が返されます。
$a = 10.011;
$b = 10.077;
floor(($a + $b) * 100) / 100; // 20.08
// OK
$a = 10.01;
$b = 10.07;
floor(($a + $b) * 100) / 100; // 20.07
// NG
対応策
floor関数の代わりにBCMath関数を使います。
BCMath関数はyumを使ってインストール可能です。
yum install php-bcmath
以下、BCmath関数を使った小数第3位切り捨てのサンプルコードです。
$a = 10.011;
$b = 10.077;
bcadd((string)$a, (string)$b, 2); // 20.08
// OK
$a = 10.01;
$b = 10.07;
bcadd((string)$a, (string)$b, 2); // 20.08
// OK
最後に
PHP界隈では、floor関数のバグは割と有名な話だそうです。
また、floor関数だけでなく、端数の切り上げに使うceil関数にも同様のバグが存在します。
多項の計算した結果を端数処理する際には、BCMath関数を使うようにしましょう。