On 04/04/2024 02:29, Jordan LeDoux wrote:
But when it comes to fixed-precision values, it should follow rules very
similar to those we discussed in the BCMath thread:
- Addition and subtraction should return a value that is the largest
scale/precision of any operands in the calculation.
- Division and multiplication should return a value that is the sum of
the scale/precision of any operands + 2 or a default (perhaps
configurable) value if the sum is small, to ensure that rounding occurs
correctly. Near zero, floats have about 12-ish decimal digits of
accuracy, and will return their full accuracy for example.
I haven't followed the discussion in the other thread, but I'm not sure
what the use case would be for a "fixed scale decimal" that followed
those rules.
As mentioned before, the use case I've encountered is money
calculations, where what people want to fix is the smallest unit of
account - e.g. €0.01 for practical currency, or €0.0001 for detailed
accounting / trading.
If I write $total = 1.03_d2; $perPerson = $total / 2; I want a result of
0.51_d2 or 0.52_d2 - that's why I specified a scale of 2 in the first place.
If I want an accurate result of 0.515_d3, I would just specify 1.03_d,
since the scale hasn't had any effect on the result.
If I want a lossless split into [0.51_d2, 0.52_d2] I still need a
function to exist somewhere, whether you spell that $total->split(2), or
decimal_split($total, 2), etc. So it seems safer to also have
$total->div(2, Round::DOWN) or decimal_div($total, 2, Round::DOWN) and
have $total / 2 give an error.
Possibly, it could only error if the result doesn't fit in the scale, so
that this would be fine: $total = 11.00_d2; $perPerson = $total / 2;
assert($perPerson === 5.50_d2)
Or possibly, it would just be an error to perform division on a fixed
scale decimal, but allowed on a variable-fixed scale decimal.
Regards,
--
Rowan Tommins
[IMSoP]