roundは四捨五入する関数です。
PHP8.4以降、この関数で小数の切り捨て切り上げができるようになります。
実はceil・floorは桁数指定ができないんですよね。
必ず整数値にさせられてしまい、小数点3桁で切り捨てみたいなことができないのであまり役に立ちません。
ということで以下は該当のRFC、Add 4 new rounding modes to round() functionの日本語訳です。
なお、この後Correctly name the rounding mode and make it an EnumというRFCも受理されて定数がENUMに置き替えられたので、置き換え後の状態で記載しています。
PHP RFC: Add 4 new rounding modes to round() function
Introduction
このRFCでは、round関数に4種類の新しいモードを追加します。
・RoundingMode::PositiveInfinity
・RoundingMode::NegativeInfinity
・RoundingMode::AwayFromZero
・RoundingMode::TowardsZero
round関数のユーザノートで最も高評価の2コメントが丸めモードについての話であり、特にトップコメントは300票以上という突出した評価を受けています。
また、NumberFormatterはここで提案するモードを既に実装しています。
Proposal
round関数の丸めモード引数として、4つのEUNUMを追加します。
・RoundingMode::PositiveInfinity 引数より大きい最小の整数に丸める。
・RoundingMode::NegativeInfinity 引数より小さい最大の整数に丸める。
・RoundingMode::AwayFromZero ゼロから離れた方に丸める。
・RoundingMode::TowardsZero ゼロに近い方に丸める。
Backward Incompatible Changes
下位互換性のない変更はありません。
Proposed PHP Versions
PHP8.4。
Questions
Why not use functions ceil() and floor()?
どうしてceil関数やfloor関数を使わないの?
ceil関数やfloor関数は整数に丸めるので、指定された桁数で丸めることができません。
round関数に渡す桁数が0の場合に完全に等しくなります。
ceil($number) === round($number, 0, RoundingMode::PositiveInfinity); //true
floor($number) === round($number, 0, RoundingMode::NegativeInfinity); //true
Why not the names PHP_ROUND_UP and PHP_ROUND_DOWN?
どうして定数名がPHP_ROUND_UP・PHP_ROUND_DOWNでないの?
ほぼ同じ定数名が既にNumberFormatterにあります。
これは『ゼロから離れた方に丸める』『ゼロに近い方に丸める』を意味していますが、CEILINGやFLOORと区別がわかりにくくたいへん曖昧であるため、ROUND_TOWARD_ZERO/ROUND_AWAY_FROM_ZEROとしました。
訳注:この後ENUMになりました。
Why not the enum implementation for the rounding modes?
丸めモードにENUMを使わないのはなぜ?
このRFCは既存関数の拡張であるため、既存の実装を踏襲しています。
ENUMの導入は、このRFCには含まれません。
訳注:この後ENUMになりました。
Proposed Voting Choices
投票期間は2023/11/15~2023/11/30、投票の2/3の賛成で受理されます。
本RFCは賛成19反対0の全会一致で可決されました。
また同時に定数ROUND_UPをROUND_AWAY_FROM_ZEROに改名しようという投票も行われたのですが、こちらは却下されました。
訳注:この後ENUMになりました。
Implementation
感想
このRFCが受理された時点では、round関数の丸めモードはこれまでのPHP_ROUND_HALF_UP・PHP_ROUND_HALF_DOWN・PHP_ROUND_HALF_EVEN・PHP_ROUND_HALF_ODDの4種類に加え、さらに4種類PHP_ROUND_CEILING・PHP_ROUND_FLOOR・PHP_ROUND_AWAY_FROM_ZERO・PHP_ROUND_TOWARD_ZEROが増えることになりました。
わかりにくい!
定数がとてもつらいということは開発陣にももちろん共有されていて、別途Correctly name the rounding mode and make it an EnumというRFCが提出されました。
こちらも無事受理されたため、結果としてPHP8.4以降はround($number, 0, \RoundingMode::HalfAwayFromZero);
のように書けるようになりました。
めでたし。
このふたつのRFCによって、関数roundは機能も増え、書き方もわかりやすくなりました。
ところでceil/floorは完全にroundの下位互換になってしまいました。
ということで、もしかしたら今後は削除されるかもしれませんね。