【PHP】number_format関数が数値を四捨五入する件
2019年10月の消費税対応している中で気づいたのですが、PHPで3桁ごとにカンマを付与して表示してくれるnumber_format関数が、じつは「小数点を含む数値」を四捨五入しいるのに気づきました。
マニュアルにもにも載っていなかった(と思う)ので、まじで驚きました。
とりあえず、備忘録として残しておきたいと思います。
PHPのnumber_format関数
今回の事例
number_format関数は、通常は以下のように使うと思います。
1 2 3 |
<?php echo number_format(1234567); // 1,234,567 ?> |
上記のように整数だと全く問題がなかったのですが、(他人が作ったシステムの)消費税関連の修正をしている中で、税抜 1,544円 のものに対して8%処理をした際、単純に8%を掛けると、1,667.52円 となる箇所がありました。
まぁ、私も小数点が出た際のことを考えて切り捨て処理を入れればよかったのですが、すっかり抜け落ちており、そのまま表示させていました。
で、この数値を含む一覧ページを作った際、なぜか1円合わないということを経理より聞きいたので調査してみると、
1 2 3 |
<?php echo number_format(1667.52); // 1,668 ?> |
となっていた次第。
で、PHPマニュアルを見たのですが、やはり載っていない。
でもよーく見てみると、実はマニュアルページの下の方に、以下のことが(10年ほど前に)書かれていました。
It's not explicitly documented; number_format also rounds:
ドキュメント化されてないけど、number_format関数は「丸め処理」をする...だと?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<?php $numbers = array(0.001, 0.002, 0.003, 0.004, 0.005, 0.006, 0.007, 0.008, 0.009); foreach ($numbers as $number) print $number."->".number_format($number, 2, '.', ',')."<br>"; ?> 0.001->0.00 0.002->0.00 0.003->0.00 0.004->0.00 0.005->0.01 0.006->0.01 0.007->0.01 0.008->0.01 0.009->0.01 |
うへぇ、確かに 0.005 を number_format すると 勝手に小数点以下が四捨五入されて 0.01 になってますね。
小数点以下を含みたい場合
小数点以下の数値も含んで number_format したい場合は、以下のように、第二引数に桁数を指定します。
1 2 3 |
<?php echo number_format(1234.567, 2); // 1,234.57 ?> |
number_formatのおさらい
PHPマニュアルはこちら。
https://www.php.net/manual/ja/function.number-format.php
概要
number_format - 数字を千位毎にグループ化してフォーマットする
説明
この関数は 1 つか 2 つもしくは 4 つのパラメータを受け取ります (3つはありません) :
- パラメータが 1 つだけ渡された場合
- number は千位毎にカンマ (",") が追加され、小数なしでフォーマットされます
- パラメータが 2 つ渡された場合
- number は decimals 桁の小数の前にドット (".") 、千位毎にカンマ (",") が追加されてフォーマットされます
- パラメータが 4 つ全て渡された場合
- number はドット (".") の代わりに dec_point が decimals 桁の小数の前に、千位毎にカンマ (",") の代わりに thousands_sep が追加されてフォーマットされます
パラメータ
- number
- フォーマットする数値。
- decimals
- 小数点以下の桁数。
- dec_point
- 小数点を表す区切り文字。
- thousands_sep
- 千位毎の区切り文字。
返り値
number をフォーマットした結果を返します。