Hi Jordan,
> For addition, it absolutely should expand scale like this, unless the
> constructor also defines a default rounding type that is used in that
> situation. All numbers, while arbitrary, will be finite, so addition will
> always be exact and known based on inputs prior to calculation.
>
> Treating scale like this isn't more strict, it's confusing. For instance:
>
> ```
> $numA = new Number('1.23', 2);
> $numB = new Number('1.23456', 5);
>
> $expandedScale1 = $numA + $numB; // 2.46456
> $expandedScale2 = $numB + $numA; // 2.46456
>
> $strictScale1 = $numA + $numB; // 2.46 assuming truncation
> $strictScale2 = $numB + $numA; // 2.46456
> ```
>
> I ran into this same issue with operand ordering when I was writing my
> operator overload RFC.
>
> There are ways you could do the overload implementation that would get around
> this for object + object operations, but it's also mathematically unsound and
> probably unexpected for anyone who is going to the trouble of using an
> arbitrary precision library.
>
> Addition and subtraction should automatically use the largest scale from all
> operands. Division and multiplication should require a specified scale.
>
> Because of this, I'm not entirely sure that specifying a scale in the
> constructor is actually a good thing. It is incredibly easy to create
> situations, unless the implementation in C is VERY careful, where the operand
> positions matter beyond the simple calculation. Multiplication is
> commutative, but division is not. This would almost certainly lead to some
> very difficult to track down bugs.
>
> Putting scale in the constructor is similar to some of the examples of
> "possible misuse cases of operator overloading" that I had to go over when I
> was making my RFC. We definitely want to avoid that if possible for the first
> number/math object that has operator overloads.
Your opinion may be reasonable given the original BCMath calculation order.
That is, do you intend code like this?
Signature:
```
// public function __construct(string|int $number)
// public function getNumber(?int $scale = null): string
```
Add:
```
// public function add(Number|string|int $number): string
$num = new Number('1.23456');
$num2 = new Number('1.23');
$add = $num + $num2;
$add->getNumber(); // '2.46456'
$add->getNumber(1); // ‘2.4'
$add = $num->add($num2);
$add->getNumber(); // '2.46456'
$add->getNumber(1); // '2.4'
```
Div:
```
// public function div(Number|string|int $number, int $scaleExpansionLimit =
10): string
// case 1
$num = new Number('0.0001');
$num2 = new Number('3');
$div = $num / $num2; // scale expansion limit is always 10
$div->getNumber(); // '0.0000333333333'
$div = $num->div($num2, 20);
$div->getNumber(); // '0.00003333333333333333333'
$div->getNumber(7); // ‘0.0000333'
// case 2
$num = new Number('1.111111');
$num2 = new Number('3');
$div = $num->div($num2, 3);
$div->getNumber(); // '0.370'
$div->getNumber(7); // ‘0.3700000'
```
Since the scale can be inferred for everything other than div, a special
argument is given only for div.
Regards.
Saki