PHPのnumber_format関数は数字を千の位毎にグループ化してフォーマットする関数です。
数値にカンマをつけたい、そんな場合に利用する関数です。
number_format関数の挙動のおさらい
number_format(float $num, /* フォーマットする数値。*/ int $decimals = 0,/* 小数点以下の桁数 */ ?string $decimal_separator = ".", /* 小数点を表す区切り文字。*/ ?string $thousands_separator = ","/* 千の位毎の区切り文字。*/ ): string
小数を含むフォーマットの場合には注意が必要です。number_format関数内で丸め(四捨五入)が働きます。
echo 12339960/1000;
結果は12339.96です。
「12,339.9」と表示させたいのですが、number_formatではうまくいきません。
echo number_format(12339960/1000,1);
結果は12,340.0です。
小数第二位で繰り上げが発生してしまいます。
number_formatの挙動は以下の通りです。
- $decimals = 0、小数第一位で繰り上げ(四捨五入)
echo number_format(12339960/1000);
結果は12,340です。
これは、下の0を小数の桁として指定した場合と同等です。echo number_format(12339960/1000,0);
結果は12,340です。
小数第一位で四捨五入されていますね。
ちなみにnumber_format(1.4)は1、number_format(1.5)は2という結果になります。 - $decimals = 1、小数第二位で繰り上げ(四捨五入)
echo number_format(12339960/1000,1);
結果は12,340.0です。
1を小数の桁と指定した場合、小数第二位で四捨五入されます。 - $decimals = 2、小数第三位で繰り上げ(四捨五入)
echo number_format(12339960/1000,2);
結果は12,339.96です。
2を小数の桁と指定した場合、小数第三位で四捨五入されます。
number_formatの四捨五入を防ぐ考え方
四捨五入の対象となる位を切り捨てします。これで四捨五入を防げます。
小数の桁 | サンプルソース |
小数の桁0 | echo number_format(floor(1.5)); floorで1.5→1にしています |
小数の桁1 | echo number_format(floor(1.55*10)/10,1); floorで15.5→15、1.5に戻しています |
小数の桁2 | echo number_format( floor(1.555*100)/100,2); 155.5→155、1.55に戻しています |
小数の桁3 | echo number_format( floor(1.5555*1000)/1000,3); |
つまり、こんな関数を用意すれば解決できます。
function my_format( float $num,int $decimals = 0,?string $decimal_separator = ".",?string $thousands_separator = ","): string{
$rate = pow( 10, $decimals);
return number_format( floor($num*$rate)/$rate , $decimals, $decimal_separator,$thousands_separator);
}
echo my_format( 12339960/1000,1 );
結果は12,339.9です。四捨五入されずに、求めている結果になりました☺️
まとめ:正の値はこれでいけます。負の値は危険かも?
正の値はこのロジックで大丈夫だと思います。負の値は、floorの挙動に納得できるなら大丈夫ですが、求めているのと違う場合、正と負で処理を切り分ける等の修正が必要です。
echo floor(4.3); // 4
echo floor(9.999); // 9
echo floor(-3.14); // -4
コメント