Re: [RFC] [Discussion] Support object type in BCMath
| From: | Saki Takamachi | Date: | Wed, 27 Mar 2024 00:36:52 +0000 |
| Subject: | Re: [RFC] [Discussion] Support object type in BCMath | ||
| References: | 1 2 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-122767@lists.php.net to get a copy of this message | ||
Hi Aleksander,
> Here's another question.
>
> 1. Since we have withScale(), do we need to inherit the $scale argument from the functional
> API? Can't we derive it from the object the method is being invoked on?
>
> So, instead, e.g.
>
> public function add(BcNum|string|int $num, ?int $scale = null): BcNum {}
> public function sqrt(?int $scale = null): BcNum {}
>
> I'd suggest:
>
> public function add(BcNum|string|int $num): BcNum {}
> public function sqrt(): BcNum {}
>
> but I have no clue about BCMath.
Yeah, you're right. By using
withScale before calculating, we can obtain results
of arbitrary precision without using Scale during calculation.
The code in that case would look like this:
```
$num = new Number('1.23');
$num2 = new Number('4.56');
$numRescaled = $num->withScale(4);
$result = $numRescaled->add($num2);
$result->value; // '5.7900'
$result->scale; // 4
```
On the other hand, if allow the calculation method to specify a scale, we can write it like this:
```
$num = new Number('1.23');
$num2 = new Number('4.56');
$result = $num->add($num2, 4);
$result->value; // '5.7900'
$result->scale; // 4
```
It's just one less line, but that's the only reason to support the $scale
argument.
However, for calculations other than mul and div, the calculation results will always fit within the
scale.
```
$num = new Number('1.23'); // scale 2
$num2 = new Number('1'); // scale 0
$num->add($num2); // '2.23', scale 2 is enough
$num->sub($num2); // '0.23', scale 2 is enough
$num->mod($num2); // '0.23', scale 2 is enough
```
On the other hand, for mul, div, and pow, the original $num scale may not be enough.
```
$num = new Number('1.23'); // scale 2
$num2 = new Number('1.1'); // scale 1
$num->mul($num2); // '1.353' be '1.35', scale 2 is not enough
```
```
$num = new Number('1.23'); // scale 2
$num2 = new Number('4'); // scale 0
$num->div($num2); // '0.3075' be '0.30', scale 2 is not enough
$num->pow($num2); // '2.28886641', be '2.28' scale 2 is not enough
```
For mul and pow, can calculate the required scale. However, for div, the calculation may never end,
such as 0.33333...., so it is not possible to calculate the scale to fit the result
completely.
In cases like this, we thought that some users would want to easily specify the scale, so we created
an easy-to-use signature.
However, it may not be necessary to specify scale for all calculation functions. Is it reasonable to
specify only mul, div, pow, or only div?
Regards.
Saki