> On 7 Dec 2023, at 13:36, Alex Pravdin <alex.prav...@interi.co> 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 


Reply via email to