On Wed, Dec 13, 2023 at 9:37 AM Stephen Reay <[email protected]> wrote:
>
>
>
> > On 7 Dec 2023, at 13:36, Alex Pravdin <[email protected]> wrote:
> >
> > Hello internals,
> >
> >
> > This is the second round of the discussion regarding arbitrary precision
> > scalar type integration into PHP. The previous part:
> > https://marc.info/?l=php-internals&m=168250492216838&w=2 was initiated by
> > me before deep diving into the work with decimals in PHP. After 6 months of
> > working, I would like to update my proposal taking into account my
> > experience and the previous discussion.
> >
> > Today's alternatives and their problems are the following.
> >
> > bcmath:
> > - Workaround: using string type.
> > - Unintuitive function calls instead of regular math operations.
> > - Unintuitive strings instead of numbers. People want to work with numbers.
> > - Can not use proper type-hinting.
> > - Can use PHP's basic type coercions.
> >
> > Ext-decimal:
> > - Third-party extension.
> > - Workaround: implements the Decimal class that allows basic regular math
> > operations.
> > - Requires using class methods for the rest of math operations.
> > - The latest release was in 2019 and there's a danger that it will be
> > unmaintained and not compatible with the future PHP releases.
> > - The php-decimal documentation website is currently down.
> > - Since objects are always casted to true when not null, "(bool)
> > Decimal(0)" will equal to true which is not intuitive.
> > - IDEs are often confused when you use math operations on objects while the
> > code works fine.
> >
> > GMP:
> > - Workaround: implements the GMP class that allows basic math operations.
> > - Requires using separate functions for the rest of operations.
> >
> > - Objects are always casted to true, GMP(0) will equal to true.
> >
> >
> > Accounting for all of the above, I suggest adding a native numeric scalar
> > arbitrary precision type called "decimal". Below are the preliminary
> > requirements for implementation.
> >
> >
> > Decimal values can be created from literals by specifying a modifier or
> > using the (decimal) typecast:
> >
> > $v = 0.2d;
> > $v = (decimal) 0.2; // Creates a decimal value without intermediary float
> >
> > It uses the precision and scale defined in php.ini.
> >
> > The "decimal" typehint allows to define custom precision and scale:
> > decimal(20,5). It accepts regular expressions returning ints in the
> > execution context. It accepts int constants and literals in class field and
> > function argument definitions.
> >
> > New functions added: get_scale and get_precision to return corresponding
> > values about a decimal value.
> >
> > If decimal value with different scale and precision is going to be assigned
> > to a variable or parameter with smaller scale or precision, it first tries
> > to convert the value. If it's not possible, then an exception is thrown
> > like "Can not convert decimal (a, b) xxxxx.yyyy to decimal(c, d)". If
> > possible, it performs the conversion and generates a warning like
> > "Assigning decimal(a, b) to decimal(c, d) may be not possible with some
> > values".
> >
> > It works the same as "float" in terms of its usage and type casting except
> > for one thing. Float value can be passed to a decimal argument or
> > typecasted with a warning like "Float to decimal conversion may incur
> > unexpected results".
> >
> > Decimal to float conversion is allowed and smooth:
> >
> > function f (float $value) {}
> >
> > f(0.2);
> >
> > f(0.2d); // allowed with no warnings
> >
> >
> > Function "str_to_decimal" added to convert string representation of numbers
> > to decimals.
> >
> >
> > Typecast from string to decimal works the same as the "str_to_decimal"
> > function.
> >
> > Function "float_to_decimal" added to explicitly convert floats to decimals.
> > It performs float to string conversions using php.ini settings as defaults
> > but also accepts parameters to configure the conversion. Then, it converts
> > string to decimal. Since the main problem of float to decimal conversion is
> > that we don't know the exact result until we use some rounding when
> > transforming it to a human-readable format, it looks like the step of the
> > conversion to a string is inevitable. Any more optimized algorithms are
> > welcome.
> >
> > Explicit typecast from float to decimal works the same as
> > "float_to_decimal" function with all default values but also throws a
> > warning. This is to encourage users to use explicit conversion with the
> > "float_to_decimal" function and control the results.
> >
> > Literal numbers in the code are converted to floats by default. If
> > prepended by the "(decimal)" typecast, the decimal result is produced
> > without an intermediary float.
> >
> > New declare directive "default_decimal" is added. When used, literals and
> > math operations return decimal by default instead of float. This is to
> > simplify creating source files working with decimals only.
> >
> > New language construct "as_decimal()" is added to produce decimal math
> > results for literals and math operations instead of float without
> > intermediary float:
> >
> > $var = 5 / 2; // returns float 2.5
> > $var = as_decimal(5 / 2); // returns decimal 2.5
> >
> > This is a kind of "default_decimal" for a specific operation.
> >
> > If mixed float and decimal operands are used in a math operation, decimal
> > is converted to float by default. If "default_decimal" directive or
> > "as_decimal()" construct is used, float is converted to decimal (with a
> > warning):
> >
> > $f = (float) 0.2;
> > $d = (decimal) 0.2;
> >
> > $r = $f + $d; // returns float result by default
> > $r = as_decimal($f + $d); // returns decimal result with a warning about
> > implicit float to decimal conversion
> >
> > All builtin functions that currently accept float also accept decimal. So
> > users don't need to care about separate function sets, and PHP developers
> > don't need to maintain separate sets of functions. If such functions get
> > the decimal parameter, they return decimal. If they have more than one
> > float parameter and mixed float and decimal passed, decimals converted to
> > float by default. If "default_decimal" or "as_decimal" used, float is
> > converted to decimal with the warning.
> >
> >
> > The new type uses libmpdec internally to perform decimal calculations (same
> > as Python).
> >
> >
> > All of the points above are subject to discussions, it is not an RFC
> > candidate right now. So please share your opinions.
> >
> > I know that the implementation of this will require a lot of work. But I
> > don't think this is a stopper from formulating the requirements. Sometimes,
> > any project requires big changes to move forward. I'm pretty sure this
> > functionality will move PHP to the next level and expand its area of
> > applications. My thoughts here are mostly from the user's perspective, I'm
> > not so familiar with PHP internal implementation. But I think this feature
> > can be a good goal for PHP 9.
> >
> >
> > --
> > Best regards,
> > Alex Pravdin
>
>
> Hi,
>
> While I do think it would be beneficial to have a built-in `decimal` type,
> regarding ext-decimal, I think some of the points raised may be outdated?
>
> The documentation site seems to have moved to https://php-decimal.github.io
> <https://php-decimal.github.io/>, which also indicates that it implements
> operator overrides.
>
>
> Cheers
>
> Stephen
>
>
Hello Stephen,
I just ran `apt install php8.3-decimal` and tried this:
$a = new Decimal\Decimal("1", 2);
$b = $a + $a;
PHP Warning: Uncaught TypeError: Unsupported operand types:
Decimal\Decimal + Decimal\Decimal in
So, it appears not.
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php