コードロード

エラー討伐

【PHP】小数点以下の桁数を指定して切り捨てる方法(floor、number_format、sprintf)

やりたいこと

ある桁数以下は切り捨てて、それより上の桁数で値を返したかった。

例えば、小数点第三位以下は切り捨てて、小数点第二位までを返したい。

課題

ググると、 floorsprintfnumber_format があるよう。

floor だと小数点以下の切り捨てて整数にするのみで、桁数の指定はできない。

sprintfnumber_format なら、小数点以下の桁数を指定するだけなので簡単そう!と思ったが、よくよく調べてみると、なぜか四捨五入されてしまうらしい。

結論

結局、完全な切り捨てを行いたいなら floor を工夫して使うのが良さそうという結論に辿り着いた。

イメージは、元の数値を割って小数点の位置を左にズラしてから floor で小数点以下を切り捨てて、割った数分、倍にすれば良い。 例えば、小数第三位以下は切り捨てたいなら、ある数値を100倍してからfloorで切り捨てて、その後で100で割って、小数第二位までに戻す。

  • もし元の数字の小数点以下の桁数が動的であれば、その数字に number_formatsprintf で桁数を揃えてから(小数点第二位までにしたければ、第三位までを一旦揃える)、 floor を使って切り捨てれば良さそう。

  • もし元の数字の小数点以下の桁数が動的であれば、その数字に number_formatsprintf で桁数を揃えてから、 floor を使って切り捨てれば良さそう。

下記のサンプルコードは下記サイトから引用。

PHP 四捨五入/切り上げ/切り捨てのサンプル

<?php

// 小数第一位で切り捨て
print floor(2.26);  // 2

// 小数第一位で切り捨て
print floor(2.82);  // 2

// マイナスの場合
print floor(-2.82); // -3

// 小数第二位で切り捨て
print (floor(12.262 * 10) / 10); // 12.2

// 小数第三位で切り捨て
print (floor(12.262 * 100) / 100); // 12.26

// 1の位で切り捨て
print (floor(122.2 / 10) * 10); // 120

// 10の位で切り捨て
print (floor(122.2 / 100) * 100); // 100

?>

小数第二位で切り捨てています。以下の操作です。 1.対象の値に10を掛けます。(12.262 * 10 = 122.62) 2.floorメソッドを使用して小数点以下を切り捨てます。(122.62 → 122) 3.対象の値を再度10で割ります。(122 / 10 = 12.2)

number_formatとsprintfの挙動

number_format

number_format

number_format(
    float $num,
    int $decimals = 0,
    ?string $decimal_separator = ".",
    ?string $thousands_separator = ","
): string

num

フォーマットする数値。

decimals

小数点以下の桁数。 0 を指定すると、 返り値の decimal_separator は省略されます。

decimal_separator

小数点を表す区切り文字。

thousands_separator

千の位毎の区切り文字。

$number = 1234.56;

// 英語での表記 (デフォルト)
$english_format_number = number_format($number);
// 1,235

$number = 1234.5678;

// 千位毎の区切りがない英語での表記
$english_format_number = number_format($number, 2, '.', '');
// 1234.57  // ここ四捨五入されてる

PHPで小数点以下を2桁とか3桁に切り捨てる2つの方法 | PisukeCode - Web開発まとめ

なぜか四捨五入されてる。切り捨てたい。

sprintf

【PHP】小数点以下まで出力する - Qiita

sprintfとprintfの違いは、sprintfはフォーマットされた値が戻り値。printfはフォーマットされた値を標準出力する。

$num1 = 10;
$num2 = 1000.5;
$num3 = 0.456789;

echo sprintf('%.2f',$num1),PHP_EOL;
echo sprintf('%.2f',$num2),PHP_EOL;
echo sprintf('%.2f',$num3),PHP_EOL;
/*
10.00
1000.50
0.46    // ここがなぜか四捨五入されてる。
*/

なぜか四捨五入されてしまう場合もあるので、切り捨て対時は使えなさそう。