rfc:fix_up_bcmath_number_class

PHP RFC: Fix up BCMath Number Class / Change GMP bool cast behavior

Introduction

Regarding RFC: Support object type in BCMath, I received several comments and suggestions, so I created this RFC to respond to them.

Also, in those discussions, there were suggestions regarding the behavior of casting GMP classes to bool, and for procedural efficiency, I will combine these into one RFC. (Each vote will be taken separately.)

Proposal

This RFC makes several corrections and changes to the BcMath\Number class and proposes to override the first RFC.

It also proposes that when a GMP object is cast to bool, change it so that 0 is false and everything else is true, like an int.

Details of the proposal regarding BCMath are as follows:

  1. Casting a Number object to bool makes it false if it is 0 and true otherwise.
  2. Of the six comparison methods comp(), eq(), gt(), gte(), lt(), lte(), remove all except comp(). Then rename the comp() method to compare().
  3. Remove format() method.
  4. Remove rounding in calculations.
  5. Make it serializable.
  6. Fixed typo in stub.

bool cast

Change both GMP and BCMath to behave like int.

BCMath

More information about comparison methods

In fact, only the comp() method is needed to fulfill the functionality of the other five methods.

Adding methods later is easy, but removing them always involves a BC Break. Providing 6 methods from the start is obviously overkill, so we will only provide comp().

By the way, the reason comp() is needed, and why comparison operators are underpowered, is to specify the scale to use for the comparison.

Currently, there is no other expression for comparison in PHP called “comp”. The expression “cmp” is mainly used for functions, and the expression “compare” is used for class methods.

e.g. https://www.php.net/manual/ja/splpriorityqueue.compare.php https://www.php.net/manual/ja/collator.compare.php

Therefore, follow these conventions and rename comp() to compare().

public function compare(Number|string|int $num, ?int $scale = null): int {}

Remove format method

The optimal format varies greatly from country to country, and the signature proposed in the original RFC is insufficient. There are also opinions that such functionality should be implemented in Intl rather than BCMath.

If released in a half-finished state, BC Break will become a problem later, so this feature will be removed. If this functionality is really needed for this class, we can always consider adding it again.

Remove rounding in calculations

The current specification does not allow calculations with operators to be used by users who do not want rounding. I also found it very inconvenient to have to specify an optional argument every time I perform a calculation using this method if I don't want rounding.

e.g.

$ret = $num->div($num2, null, PHP_ROUND_TOWARD_ZERO);

If the default behavior is “no rounding”, i.e., truncation behavior like the existing BCMath functions, if you want to perform rounding, you can simply use the round() method.

$ret = $num->div($num2)->round(2);

Based on the idea that we shouldn't provide an API that looks “rich” from the get-go, I suggest removing all of these roundings.

In other words, the rounding mode during calculations will be fixed at truncation, and the user will not be able to change it. This applies to both operator and method calculations.

If the user wants to do rounding, the round() method should be used.

Make it serializable

Being serializable is very important when using something like Redis, as this is expected to be used as a value object. This probably doesn't require an RFC on its own, but I mention it to keep things clear.

Fixed typo in stub

This probably doesn't require an RFC per se, but I'll make it explicit to keep things clear.

public function pow(Number|string|int $exponent, int $minScale, ?int $scale = null, int $roundingMode = PHP_ROUND_HALF_UP): Number {}

I forgot to delete int $minScale in this signature. Correctly, it should look like this:

public function pow(Number|string|int $exponent, ?int $scale = null, int $roundingMode = PHP_ROUND_HALF_UP): Number {}

Backward Incompatible Changes

BCMath: None.

GMP: Code like if ($gmp) {} will behave differently. However, due to the nature of GMP, such code is likely to be quite rare.

Proposed PHP Version(s)

next PHP 8.x (8.4)

RFC Impact

To SAPIs

None.

To Existing Extensions

BCMath: only BCMath

GMP: only GMP

To Opcache

None.

New Constants

None.

php.ini Defaults

None.

Open Issues

None.

Unaffected PHP Functionality

BCMath: nothing other than BCMath is affected.

GMP: nothing other than GMP is affected.

Future Scope

BCMath: Methods removed in this RFC may be considered for implementation again in the future. However, there are no specific plans at this time.

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.

This RFC combines two RFCs into one for procedural efficiency, and the BCMath and GMP proposals will be voted on separately. This means that the two RFCs are completely independent and do not influence each other's voting results.

These are not second-round votes, so each requires a two-thirds majority vote to pass.

Voting ends on 2024-07-30 00:00:00 UTC.

Fix up BCMath Number Class
Real name Yes No
crell (crell)  
derick (derick)  
ericmann (ericmann)  
galvao (galvao)  
girgias (girgias)  
jimw (jimw)  
kguest (kguest)  
kocsismate (kocsismate)  
mauricio (mauricio)  
petk (petk)  
pierrick (pierrick)  
ramsey (ramsey)  
rasmus (rasmus)  
saki (saki)  
sergey (sergey)  
timwolla (timwolla)  
weierophinney (weierophinney)  
zeriyoshi (zeriyoshi)  
Final result: 18 0
This poll has been closed.

Change GMP bool cast behavior
Real name Yes No
crell (crell)  
derick (derick)  
ericmann (ericmann)  
galvao (galvao)  
girgias (girgias)  
jimw (jimw)  
kguest (kguest)  
kocsismate (kocsismate)  
levim (levim)  
mauricio (mauricio)  
petk (petk)  
pierrick (pierrick)  
ramsey (ramsey)  
rasmus (rasmus)  
saki (saki)  
sergey (sergey)  
timwolla (timwolla)  
weierophinney (weierophinney)  
zeriyoshi (zeriyoshi)  
Final result: 19 0
This poll has been closed.

Patches and Tests

None.

Implementation

References

Rejected Features

Some methods will be removed, but since this class has not been released yet, essentially no functionality will be removed.

rfc/fix_up_bcmath_number_class.txt · Last modified: 2024/09/04 02:15 by saki