====== PHP RFC: Adding bcround, bcfloor and bcceil to BCMath ====== * Version: 0.1.0 * Date: 2023-10-01 * Author: Saki Takamachi, saki@sakiot.com * Status: Implemented * Target Version: PHP 8.4 * Implementation: https://github.com/php/php-src/pull/13096 * First Published at: https://wiki.php.net/rfc/adding_bcround_bcfloor_bcceil_to_bcmath ===== Introduction ===== As you know, BCMath is an arbitrary precision mathematical function that supports exact calculations. As of the writing of this RFC, nine calculation functions exist, but no equivalents exist for round, floor, and ceil. Considering the role of BCMath, supporting features like these is important. ===== Proposal ===== This RFC proposes to introduce three new functions to BCMath: bcround(), bcfloor(), and bcceil(). It is assumed that the usage will be the same as round(), floor(), and ceil(), except that the value passed to the argument and the return value will be of string type. var_dump(bcround('0.285', 2, PHP_ROUND_HALF_UP)); // string(4) "0.29" var_dump(bcfloor('13.0915')); // string(2) "13" var_dump(bcceil('24.00001')); // string(2) "25" Since it is an arbitrary precision calculation, there is no need to consider the maximum value of int or double. var_dump(bcround('0.12345678901234567890123456789', 28)); // string(30) "0.1234567890123456789012345679" var_dump(bcfloor('123456789012345678901234567890.5')); // string(30) "123456789012345678901234567890" var_dump(bcceil('123456789012345678901234567890.5')); // string(30) "123456789012345678901234567891" ==== Round mode constant ==== Similar to round(), we can specify how edge cases are handled using mode. I plan to use the constants for round() included in standard ext as they are. The reason for reusing standard ext constants is as follows. * standard ext is installed by default * It is not a constant that expresses a complex concept enough to prepare a new constant for BCMath * Having multiple similar constants is unfriendly * These constants do not change frequently, and reusing them does not impede maintenance ==== Ignore BCMath scale ==== BCMath allows you to specify the scale of calculation results. You can pass values ​​to arguments on a per-function basis, or you can set default values ​​for BCMath and omit arguments. Due to their nature, there is no point in setting the scale of the three functions proposed this time. Therefore, these functions ignore scale settings both semantically and implementationally. You might think that it can be used to specify the precision of round, but scale does not accept negative values. This cannot be used because precision must accept negative values. ===== Backward Incompatible Changes ===== These are new features and do not break existing functionality. If I had to point out my concerns, I would say that code that satisfies the following conditions will cause an error to occur. * A situation where the user has defined a function with the same name, such as bcround() * And, the existence of the function is not checked in advance. However, I do not think it is necessary to consider these matters. ===== Proposed PHP Version(s) ===== next PHP 8.x (Probably 8.4) ===== RFC Impact ===== ==== To SAPIs ==== None. ==== To Existing Extensions ==== Only BCMath is affected. ==== To Opcache ==== No impact. ==== New Constants ==== None. ==== php.ini Defaults ==== None. ===== Open Issues ===== None. ===== Unaffected PHP Functionality ===== There is no effect on anything other than BCMath. ===== Future Scope ===== None. ===== Proposed Voting Choices ===== As per the voting RFC a yes/no vote with a 2/3 majority is needed for this proposal to be accepted. Voting started on 2023-11-15 and will end on 2023-11-30 00:00 GMT. * Yes * No ===== Patches and Tests ===== I am currently creating a prototype. ===== Implementation ===== https://github.com/php/php-src/pull/13096 ===== Rejected Features ===== None. ===== References ===== https://www.php.net/manual/en/book.bc.php https://www.php.net/manual/en/function.round.php https://www.php.net/manual/en/function.floor.php https://www.php.net/manual/en/function.ceil.php ===== Changelog ===== * 0.1.0: created rfc