Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:127757 X-Original-To: internals@lists.php.net Delivered-To: internals@lists.php.net Received: by lists.php.net (Postfix, from userid 65534) id 5AA9D1A00BD; Thu, 26 Jun 2025 14:31:56 +0000 (UTC) To: internals@lists.php.net Date: Thu, 26 Jun 2025 10:31:55 -0400 Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net x-ms-reactions: disallow MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Content-Language: en-US Subject: [PHP-DEV] Allow BcMath\Number to work identically to bcmath functions Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Posted-By: 108.45.151.232 Message-ID: <20250626143156.5AA9D1A00BD@lists.php.net> From: zimzat@zimzat.com (Russell Lee) When `BcMath\Number` was introduced it allowed `string|int` method arguments. According to a separate RFC to allow `int` to the functions this was done as a performance optimization. Unfortunately this also means it effectively disallows `float` types because PHP will truncate them to integers (and emit a deprecation report) instead of preserving them as strings. Example: https://3v4l.org/Bi5Kl ```php var_dump( (string)new BcMath\Number(5)->sub(4.2, 1), bcsub(5, 4.2, 1), ); string(3) "1.0" string(3) "0.8" ``` Per SakiTakamachi: > If there is strong demand for creating the object from a `float`, it would be better to add support for `float` rather than removing `int` from the signature. > As with the bc functions, converting a `float` to a `string` can be easily handled within php-src. > > In any case, discussion on the mailing list is necessary. I was hoping to be able to use Number as a drop-in replacement for various operations, especially back-of-the-napkin calculations, but this behavior makes it too easy to accidentally write `$number * 1.2` and get unexpected results. There are many arguments that could be made that float is the wrong type, that it has rounding issues, and possibly other edge cases, but in the vast majority of cases `(string)$float` does exactly what is expected. The lack of a non-float decimal numeric type doesn't leave much room for native expression short of doing `Number((string)$i) * Number((string)$j)` or `Number('1.2') * '1.2'`. The expectation is that in PHP 9.0 float-to-int will be disallowed and would automatically drop back to float-to-string in this case, but that is still a long way away and would mean being unable to recommend using Number in 8.4, 8.5, and beyond. Request context and discussion: https://github.com/php/php-src/issues/18674 BcMath\Number RFC: https://wiki.php.net/rfc/support_object_type_in_bcmath bcmath function int type RFC: https://wiki.php.net/rfc/allow_int_args_to_bcmath_function