Hello internals, While reviewing the PR for the "Adding bcround, bcfloor and bcceil to BCMath" RFC [1] with the different rounding modes, I was made aware of the unfortunate wrong terminology usage of PHP_ROUND_HALF_UP and PHP_ROUND_HALF_DOWN.
Indeed, PHP_ROUND_HALF_UP is implemented as "rounding half away from zero" and not "rounding half up" (which is also called rounding toward positive infinity). The behaviour for positive numbers is the same, however for negative numbers the rounding *is* different. In the same vein, PHP_ROUND_HALD_DOWN is implemented as "rounding half toward zero" and not "rounding half down" (/round half toward negative infinity). Taking -1.5 as our number: - Rounding half-up: -1 - Rounding half away from zero: -2 - Rounding half-down: -2 - Rounding half towards zero: -1 For a detailed explanation about rounding, the Wikipedia page is of great use. [2] And the following rounding calculator on Calculator Soup is useful to check the differences and behaviour of different rounding modes. [3] It should be noted that PHP is in good company about being wrong about those two rounding modes, Java, Python, and Ruby (and probably others) are also wrong in this regard. Considering that PHP 8.4 is also adding new rounding modes via the "Add 4 new rounding modes to round() function" RFC [4] attempting to solve this issue in this next version of PHP seems like a good idea. In my discussions with Saki about this issue, it seems that her and Tim have thought about creating a new enum for rounding modes, looking something like this: enum RoundingMode { case HalfAwayFromZero; case HalfTowardsZero; case HalfEven; case HalfOdd; case TowardsZero; case AwayFromZero; case NegativeInfinity; // or case Floor; case PositiveInfinity; // or case Ceiling; } and change the signature of round from: round(int|float $num, int $precision = 0, int $mode = PHP_ROUND_HALF_UP): float to round(int|float $num, int $precision = 0, RoundingMode $mode = RoundingMode::HalfAwayFromZero): float and changing the definition of the existing constants to effectively be: define('PHP_ROUND_HALF_UP', RoundingMode::HalfAwayFromZero); define('PHP_ROUND_HALF_DOWN', RoundingMode::HalfTowardsZero); define('PHP_ROUND_HALF_EVEN', RoundingMode::HalfEven); define('PHP_ROUND_HALF_ODD', RoundingMode::HalfOdd); This should not cause any BC breaks, while allowing us to potentially implement the half up/down rounding modes properly, and deprecate the existing rounding constants in the future to get rid of the confusing names. I wanted to know if anyone has any object to introducing this new enum and signature change. The only thing I could think of is if this enum should be in a new Maths (or Math or just Mathematics to not need to deal with regional difference in the short spelling of "Mathematics") namespace. Best regards, Gina P. Banyard [1] https://wiki.php.net/rfc/adding_bcround_bcfloor_bcceil_to_bcmath [2] https://en.wikipedia.org/wiki/Rounding [3] https://www.calculatorsoup.com/calculators/math/rounding-methods-calculator.php [4] https://wiki.php.net/rfc/new_rounding_modes_to_round_function