round($x)はいちばん近い整数に丸め(四捨五入)、floor($x)は常に切り捨て、ceil($x)は常に切り上げます。小数点以下の桁数はround()の2つ目の引数で指定します:round(3.14159, 2)は3.14です。
3つとも、値が整数でもfloatを返します。var_dump(round(5))はfloat(5)と表示するので、整数が必要なら(int)でキャストします。
小数点以下2桁に丸める
round()の2つ目の引数は精度です。正の数ならその桁数の小数に丸めます。負の数なら小数点より左で丸めるので、「約1,200人の訪問者」のような概数に便利です。
floatには何個のゼロが欲しかったかという情報がないので、round(3.10, 2)は3.1と表示されます。数値をページに表示する場合(価格、パーセンテージ)は、代わりに書式を整えます。number_format()はnumber_format(3.1, 2)で3.1を"3.10"にし、sprintf('%.2f', $x)も同じことをします。
半分を切り上げるか、切り捨てるか、偶数にするか
デフォルトでは、round()はちょうど半分の値を0から遠い方向に丸めます。多くの人が学校で習った四捨五入です。3つ目の引数で、2つの数のちょうど中間にある値に対する別のルールを選べます。
PHP_ROUND_HALF_EVENは「銀行家の丸め」です。半分はいちばん近い偶数に丸められるので、たくさんの値を丸めても、時間とともに上方向へずれていきません。会計のコードではこれが求められることがよくあります。
負の数に対するfloorとceil
floor()は負の無限大の方向へ、ceil()は正の無限大の方向へ動きます。負の数では驚かれることがあり、floor(-3.5)は-3ではなく-4です。小数部分を0の方向へ切り捨てたいなら、代わりにintにキャストします。
ページ数の行はceil()の典型的な使い方です。1つでも余りが出れば、もう1ページ必要になります。
整数の割り算と剰余
/は割り切れないときfloatを返すので、7 / 2は3.5です。整数の割り算には余りを捨てるintdiv()を、余りそのものには%を使います。
%は先に両方のオペランドを整数に変換するので7.5 % 2は1になり、PHP 8.1以降はDeprecated: Implicit conversion from float 7.5 to int loses precisionも表示されます。小数部分が重要ならfmod()を使いましょう。PHP 8では、/、intdiv()、%でゼロ除算するとDivisionByZeroErrorが投げられるので、割る数が入力から来るときは先に確認してください。
べき乗、平方根、abs、max、min
**はべき乗(pow()も同じ)、sqrt()は平方根、abs()は符号を取り除きます。max()とmin()は複数の引数か、1つの配列を受け取ります。
**は右から左に評価されるので、2 ** 3 ** 2は2 ** 9の意味です。max(0, min(100, $x))の組み合わせは、値を下限と上限の間に収める定番の方法です。円の計算で円周率が必要ならM_PIに入っています。
random_intとrandによる乱数
random_int($min, $max)は、両端を含むランダムな整数を返します。実行のたびに出力が変わるので、何回かRunを押してみてください。
ログインコード、トークン、パスワードリセットのリンクなど、セキュリティに関わるものにはrandom_int()を使います。rand()とmt_rand()も今まで通り動き、同じ($min, $max)の引数を受け取りますが、その数列は予測できます。安全な乱数源でシャッフルや抽出をするために、PHP 8.2でRandom\Randomizer($r->getInt(1, 6)、$r->shuffleArray($a))が追加されました。
floor()がときどき間違った答えを返す理由
floatは2進数で保存され、多くの10進数の値(0.1など)は正確には保存できません。たいていは表示するときに隠れますが、floor()と(int)は丸めずに切るので、7.999999999のような値は7になります。
金額のように正確な小数が必要なときは、最小単位の整数で保存し(19.99ではなく1999のようにセント単位の整数)、表示するときだけ割ります。最後の行のように、floor()やceil()の前に適切な精度で丸めることでも、ほとんどのケースは解決します。
よくある質問
PHPで小数点以下2桁に四捨五入するには?
2つ目の引数に小数点以下の桁数を渡します:round(3.14159, 2)は3.14を返します。戻り値はfloatなので、桁数を固定して表示するには(3.1ではなく3.10)、number_format($x, 2)かsprintf('%.2f', $x)を使います。
PHPで切り捨てるには?
floor($x)は1つ下の整数に切り捨てます:floor(4.9)は4、floor(-4.1)は-5です。0の方向へ小数部分を落としたい場合は(int) $xでキャストします。こちらは-4.9を-4にします。
PHPのround()がfloatを返すのはなぜですか?
round()、floor()、ceil()は、結果が整数でも常にfloatを返します:var_dump(round(5))はfloat(5)と表示します。配列の添字などで整数が必要なときは、呼び出しを(int)かintval()で包みます。
PHPのrand()とrandom_int()の違いは何ですか?
random_int(1, 6)は暗号論的に安全な乱数源を使うので、トークン、コード、ユーザーが推測を試みそうなものにはこちらを使います。rand()とmt_rand()は速いですが予測できます。3つとも範囲の両端を含みます。
PHPで割り算の余りを求めるには?
整数には%演算子を使います:17 % 5は2です。結果の符号は左側のオペランドと同じなので、-7 % 3は-1です。floatにはfmod(7.5, 2)を使い、1.5が返ります。