On 07/04/2024 20:55, Jordan LeDoux wrote:

I have been doing small bits of work, research, and investigation into an MPDec or MPFR implementation for years, and I'm likely to continue doing my research on that regardless of whatever is discussed in this thread.


I absolutely encourage you to do that. What I'm hoping is that you can share some of what you already know now, so that while we're discussing BCMath\Number, we can think ahead a bit to what other similar APIs we might build in the future. The below seems to be exactly that.



Yes. BCMath uses fixed-scale, all the other libraries use fixed-precision. That is, the other libraries use a fixed number of significant digits, while BCMath uses a fixed number of digits after the decimal point.


That seems like a significant difference indeed, and one that is potentially far more important than whether we build an OO wrapper or a "scalar" one.


So, for instance, it would not actually be possible without manual rounding in the PHP implementation to force exactly 2 decimal digits of accuracy in the result and no more with MPDec.


The current BCMath proposal is to mostly choose the scale calculations automatically, and to give precise control of rounding. Neither of those are implemented in libbcmath, which requires an explicit scale, and simply truncates the result at that point.

That's why I said that the proposal isn't really about "an OO wrapper for BCMath" any more, it's a fairly generic Number API, with libbcmath as the back-end which we currently have available. So thinking about what other back-ends we might build with the same or similar wrappers is useful and relevant.


The idea of money, for instance, wanting exactly two digits would require the implementation to round, because something like 0.00000013 has two digits of *precision*, which is what MPDec uses, but it has 8 digits of scale which is what BCMath uses.


This brings us back to what the use cases are we're trying to cover with these wrappers.

The example of fixed-scale money is not just a small niche that I happen to know about: brick/money has 16k stars on GitHub, and 18 million installs on Packagist; moneyphp/money has 4.5k stars and 45 million installs; one has implementations based on plain PHP, GMP, and BCMath; the other has a hard dependency on BCMath.

Presumably, there are other use cases where working with precision rather than scale is essential, maybe just as popular (or that could be just as popular, if they could be implemented better).

In which case, should we be designing a NumberInterface that provides both, with BCMath having a custom (and maybe slow) implementation for round-to-precision, and MPDec/MPFR having a custom (and maybe slow) implementation for round-to-scale?

Or, should we abandon the idea of having one preferred number-handling API (whether that's NumberInterface or a core decimal type), because no implementation could handle both use cases?


Regards,

--
Rowan Tommins
[IMSoP]

Reply via email to