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

- Status: Implemented (PHP 8.4)
- Authors: Saki Takamachi (saki@php.net)
- Date: 2024-06-30
- Version: 1
- Original: https://wiki.php.net/rfc/fix_up_bcmath_number_class
- Page: https://externals.io/rfc/fix_up_bcmath_number_class
- More for agents: search with https://externals.io/search.md?q={query} · RFCs at https://externals.io/rfc.md · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

## Votes

### Fix up BCMath Number Class (closed)

Yes: 18 · No: 0

Voters: crell (Yes), derick (Yes), ericmann (Yes), galvao (Yes), girgias (Yes), jimw (Yes), kguest (Yes), kocsismate (Yes), mauricio (Yes), petk (Yes), pierrick (Yes), ramsey (Yes), rasmus (Yes), saki (Yes), sergey (Yes), timwolla (Yes), weierophinney (Yes), zeriyoshi (Yes)

### Change GMP bool cast behavior (closed)

Yes: 19 · No: 0

Voters: crell (Yes), derick (Yes), ericmann (Yes), galvao (Yes), girgias (Yes), jimw (Yes), kguest (Yes), kocsismate (Yes), levim (Yes), mauricio (Yes), petk (Yes), pierrick (Yes), ramsey (Yes), rasmus (Yes), saki (Yes), sergey (Yes), timwolla (Yes), weierophinney (Yes), zeriyoshi (Yes)

## Discussions on the mailing list

- [\[Discussion\] Follow-up RFC for BCMath\Number object](https://externals.io/message/123323.md) — started on 2024-05-16, 4 messages
- [\[RFC\] \[Discussion\] Fix up BCMath Number Class / Change GMP bool cast behavior](https://externals.io/message/124104.md) — started on 2024-06-30, 11 messages
- [\[RFC\] \[Vote\] Fix up BCMath Number Class / Change GMP bool cast behavior](https://externals.io/message/124430.md) — started on 2024-07-15, 2 messages

---

## Introduction

Regarding [RFC: Support object type in BCMath](https://externals.io/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()`.

```php
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.

```php
$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.

```php
$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.

```php
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:

```php
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.

**Vote: Fix up BCMath Number Class** — Yes: 18 · No: 0 (closed)

---

**Vote: Change GMP bool cast behavior** — Yes: 19 · No: 0 (closed)

## Patches and Tests

None.

## Implementation

<https://github.com/php/php-src/pull/13741><https://github.com/php/php-src/pull/15151>

## References

[https://wiki.php.net/rfc/support\_object\_type\_in\_bcmath](https://externals.io/rfc/support_object_type_in_bcmath)

<https://externals.io/message/123323>

## Rejected Features

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