やりたいこと
浮動小数点数の切り捨て処理を行い、float 型を int 型にしたい。
-
floor()
関数 - intのキャスト処理
のどちらを利用するのが適切か。それとも、どちらでも差異はないのか。
結論
-
floor()
関数は返り値として float型を返すため、int型でキャストする必要がある。 - マイナス値を扱う場合において、
floor()
と(int)
の結果が異なってくる。
そのため、
- -1.1を切り捨てした際、-1になるのが自然と感じるのであれば、
(int)$num
とする - -1.1を切り捨てした際、-2になるのが自然と感じるのであれば、
(int)floor($num)
とする
という選択肢の、どちらかを選ぶのがよいと考えられる。
マイナス値を与えたときの処理の違いについて
floor()
関数の場合
value をこえない最大の整数の値を返します。 floor() の返り値は float 型のままとなります。
https://www.php.net/manual/ja/function.floor.php
マイナス値 (例: -1.1
) を与えると、-2
を返す
<?php
$float_vals = array(1.1, 1.8, -1.1, -1.8, 0.05, -0.05);
foreach ($float_vals as $v) {
var_dump(floor($v));
}
float(1)
float(1)
float(-2) *
float(-2) *
float(0)
float(-1) *
(int)
キャストの場合
float から整数に変換する場合、その数はゼロのほうに丸められます。
https://www.php.net/manual/ja/language.types.integer.php
マイナス値 (例:-1.1
) を与えると、-1
を返す
<?php
$float_vals = array(1.1, 1.8, -1.1, -1.8, 0.05, -0.05);
foreach ($float_vals as $v) {
var_dump((int)$v);
}
int(1)
int(1)
int(-1) *
int(-1) *
int(0)
int(0) *
マイナス値の切り上げ・切り捨て処理には、4種類あるみたい
- 0への丸め
- 無限大への丸め
- 負の無限大への丸め
- 正の無限大への丸め
wikipedia - 端数処理
※ wikipediaまでしか確認していないため、本当にこのような用語が定義されているかについてはわかりません。参考程度にお願いします。
floor() 関数はなぜ値をfloat型で返すのか
表すことのできる数値の範囲を大きく取るためです。
以下記事のコメントにて、説明がありました。
https://qiita.com/takepan/items/ff8bba234fdc93a32791#comment-50d3e6e3db22ffdd53da
floorは返り値として float を返すため、取り得る値の範囲が広くなります。
floatであれば格納可能な値 9223372036854775808 をintにキャストすると、オーバーフローを引き起こします。
実際にコメントのサンプルコードを実際に実行すると、以下のようになります。
<?php
$large_number = PHP_INT_MAX + 100.1;
var_dump(sprintf('%.30f', floor($large_number)));
var_dump(sprintf('%.30f', intval(floor($large_number))));
?>
string(50) "9223372036854775808.000000000000000000000000000000"
string(51) "-9223372036854775808.000000000000000000000000000000"
オーバーフローしました。
おわりに
思いの外深い話題でした。
もっと掘り下げられそうなのですが、下書きが10件溜まってしまったため一度記事にします1
-
この記事を書くのに疲れて、結局今日書こうと思っていた記事は書けそうにない。。。あとおなかすいた ↩