Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:122000 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 96901 invoked from network); 13 Dec 2023 09:11:58 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 13 Dec 2023 09:11:58 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id B1163180031 for ; Wed, 13 Dec 2023 01:12:14 -0800 (PST) X-Spam-Checker-Version: SpamAssassin 4.0.0 (2022-12-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_PASS,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE, SPF_PASS autolearn=no autolearn_force=no version=4.0.0 X-Spam-Virus: No X-Envelope-From: Received: from mail-oo1-f46.google.com (mail-oo1-f46.google.com [209.85.161.46]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Wed, 13 Dec 2023 01:12:14 -0800 (PST) Received: by mail-oo1-f46.google.com with SMTP id 006d021491bc7-5906988ab8dso2816414eaf.0 for ; Wed, 13 Dec 2023 01:11:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1702458717; x=1703063517; darn=lists.php.net; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=i8hpwqQkEwsfOrPS32SoitvEI2upxO1f71bbzETz7KU=; b=aUPBmj/FAIFZBzslHthPbMbWHH96lktbf5lV3cyYj4BmQ7T09Cu73VmVqbxlEcVemo f4JMdDqnBeUxsYpT9g0OxVBip5pNq0PyFh+SRJDZB6WnyhSiZr1ZO9ffqt8qOg7HZpYh EDByvotNx9townIcuWm3jHVU/MLiVNJTgHbrKPOQ70RC86hvFn41GcQ1uGFXhg8ae8u8 Lj6Rw8YN0MDlKqg6D3qtRQMYX5w6ijRGXjkftvbAl4OkxiQKBgkdWYz94GD7sIdQBS0n bmIlbHBIKzPIe+Na4fgQfKe0T73fFpNrHVP8aPRYVeY2zEG80AVNvneDYpIx9vavhWl8 //mw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702458717; x=1703063517; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=i8hpwqQkEwsfOrPS32SoitvEI2upxO1f71bbzETz7KU=; b=PH3gghy/fOC0roCO9HTY4yafhyvodPeKJPg+kd41x37l+j9SFOuxGql+7y5x6PHWO8 ILsLyWrYxm2iufruxO+xdPZVsQ90qdEwV32EK9DgzsAHiBODg8G80z8dkQgzgh2mELw8 LZFtLAdEZGgHK/WxaRxD6cT3G+YTHO4HFmzABJQAxl/THoCUwwrmsd3O0mJIrLwIAnRO ZIAo/7+FClQ3MCQmwyxp7KYNUS4qK2hw/3Zy5uC22CYNWGbRA8DEZac9EaoOf5+T34Z2 AxTNxMmXAB9QKUhHSh6I/ZhZvGH0b3aUDEuVWYS9eTmabKaTyXz0nEkXhVFPOg77LolV 5D0A== X-Gm-Message-State: AOJu0YyTQtmQFB8NtmIF1JlA58hpCRdUnN5G4ctoDG/4Qy49qQSf4t3W toK4DddKrzlnXC73RNHpw9mEX+Jk28KD+fzssns= X-Google-Smtp-Source: AGHT+IFeepqaTLOqGqHAZMaftf19zjDTrCZf3CioI6Yz3QRm+vCfORE/NxtqmeivI2csVSp35Hzp0WMW263CrEFKoxw= X-Received: by 2002:a05:6870:3511:b0:203:f94:e552 with SMTP id k17-20020a056870351100b002030f94e552mr1247106oah.11.1702458716484; Wed, 13 Dec 2023 01:11:56 -0800 (PST) MIME-Version: 1.0 References: <18c42fdbb30.2831.17a3710df6d58f02ca570cc47e197a63@interi.co> <21E561F4-8893-4825-A2A9-15B305376864@koalephant.com> In-Reply-To: <21E561F4-8893-4825-A2A9-15B305376864@koalephant.com> Date: Wed, 13 Dec 2023 10:11:45 +0100 Message-ID: To: Stephen Reay Cc: Alex Pravdin , internals@lists.php.net Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Subject: Re: [PHP-DEV] Proposal: Arbitrary precision native scalar type From: landers.robert@gmail.com (Robert Landers) On Wed, Dec 13, 2023 at 9:37=E2=80=AFAM Stephen Reay wrote: > > > > > On 7 Dec 2023, at 13:36, Alex Pravdin wrote: > > > > Hello internals, > > > > > > This is the second round of the discussion regarding arbitrary precisio= n scalar type integration into PHP. The previous part: https://marc.info/?l= =3Dphp-internals&m=3D168250492216838&w=3D2 was initiated by me before deep = diving into the work with decimals in PHP. After 6 months of working, I wou= ld like to update my proposal taking into account my experience and the pre= vious 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 numb= ers. > > - 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 ma= th 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 u= nmaintained 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) Decima= l(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 operation= s. > > - 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 scal= ar arbitrary precision type called "decimal". Below are the preliminary req= uirements for implementation. > > > > > > Decimal values can be created from literals by specifying a modifier or= using the (decimal) typecast: > > > > $v =3D 0.2d; > > $v =3D (decimal) 0.2; // Creates a decimal value without intermediary f= loat > > > > It uses the precision and scale defined in php.ini. > > > > The "decimal" typehint allows to define custom precision and scale: dec= imal(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 correspondin= g values about a decimal value. > > > > If decimal value with different scale and precision is going to be assi= gned to a variable or parameter with smaller scale or precision, it first t= ries to convert the value. If it's not possible, then an exception is throw= n like "Can not convert decimal (a, b) xxxxx.yyyy to decimal(c, d)". If pos= sible, it performs the conversion and generates a warning like "Assigning d= ecimal(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 exc= ept for one thing. Float value can be passed to a decimal argument or typec= asted 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 num= bers 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 decim= als. It performs float to string conversions using php.ini settings as defa= ults but also accepts parameters to configure the conversion. Then, it conv= erts string to decimal. Since the main problem of float to decimal conversi= on is that we don't know the exact result until we use some rounding when t= ransforming it to a human-readable format, it looks like the step of the co= nversion to a string is inevitable. Any more optimized algorithms are welco= me. > > > > Explicit typecast from float to decimal works the same as "float_to_dec= imal" function with all default values but also throws a warning. This is t= o encourage users to use explicit conversion with the "float_to_decimal" fu= nction and control the results. > > > > Literal numbers in the code are converted to floats by default. If prep= ended by the "(decimal)" typecast, the decimal result is produced without a= n intermediary float. > > > > New declare directive "default_decimal" is added. When used, literals a= nd math operations return decimal by default instead of float. This is to s= implify 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 intermedi= ary float: > > > > $var =3D 5 / 2; // returns float 2.5 > > $var =3D 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, decim= al 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 =3D (float) 0.2; > > $d =3D (decimal) 0.2; > > > > $r =3D $f + $d; // returns float result by default > > $r =3D as_decimal($f + $d); // returns decimal result with a warning ab= out 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 developer= s 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 floa= t 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 ca= ndidate 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. Sometime= s, any project requires big changes to move forward. I'm pretty sure this f= unctionality will move PHP to the next level and expand its area of applica= tions. 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 , which also indicates that it implement= s operator overrides. > > > Cheers > > Stephen > > Hello Stephen, I just ran `apt install php8.3-decimal` and tried this: $a =3D new Decimal\Decimal("1", 2); $b =3D $a + $a; PHP Warning: Uncaught TypeError: Unsupported operand types: Decimal\Decimal + Decimal\Decimal in So, it appears not.