Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:123221 X-Original-To: internals@lists.php.net Delivered-To: internals@lists.php.net Received: from php-smtp4.php.net (php-smtp4.php.net [45.112.84.5]) by qa.php.net (Postfix) with ESMTPS id 1AA9E1A009C for ; Sun, 28 Apr 2024 06:02:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1714284200; bh=gaH4W0zCdKof5zfsfQkEntK61qe79URA4z4uMCrQZSs=; h=References:In-Reply-To:From:Date:Subject:To:Cc:From; b=mXlo6E98yKd60IXgqu+ZPvB3Onoi7gjW3onfTTohrj4Q8VbDg+RuRNLRfRnMIZdpT DO7kFi7m1pwDecHi0+GRHG0tDgjZ1K5tezJPbJVseJdHVB2JKVyS15afeksHqOLTu3 fGRbP+oNtbkVoYkIWTfbWS41F7d5pdn9I4v8mCvpfHQSehquqrvqX90GGsUJJHkS06 0qSk22empsCr6n1cmemZvF8/YQN+iUUoKFjijDLruzP6O2oQ4kl+ZkN/k52N8hRWwA RfEfufdImUSACBAmNQDbtakF8KzKu/skDfeHlX/eJCjvepwxtSfrJpGiaqozYovtie PLlPhbJzmWp+g== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 2CD4618006C for ; Sun, 28 Apr 2024 06:03:19 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.0 (2022-12-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=0.8 required=5.0 tests=BAYES_50,DKIM_SIGNED, DKIM_VALID,DMARC_MISSING,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2, SPF_HELO_NONE,SPF_NONE,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=4.0.0 X-Spam-Virus: No X-Envelope-From: Received: from mail-yb1-f176.google.com (mail-yb1-f176.google.com [209.85.219.176]) (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 ; Sun, 28 Apr 2024 06:03:18 +0000 (UTC) Received: by mail-yb1-f176.google.com with SMTP id 3f1490d57ef6-d9b9adaf291so3659990276.1 for ; Sat, 27 Apr 2024 23:02:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=interi-co.20230601.gappssmtp.com; s=20230601; t=1714284155; x=1714888955; 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=gaH4W0zCdKof5zfsfQkEntK61qe79URA4z4uMCrQZSs=; b=aOgZKGpxbcLLuEc51b9JouOa1VcCIAFc9BebPvycPvQ4WcKVQgwFOvA3lOenCkh+1z cDTxnQqLlF3OToBBkANsEgkCFwEUg2KITyrVHy2H+0U6HbMU1NdB77Vo4Pu9N7/Zwxx5 Gc5IizbZkqlOLQI9mCV5kqtlVyni4lHRTgvysRIjG2VJkVijull1wuJWuX1DMMvVPStx pbf/m1lPGSsO97xNDWy4skQNW2RuSmau5atNXdoGPmNrkHXu6hk5uBHhV6DTN17M6mj1 IUivzOqMbDWUQLrrVGUKY1GvLq4+71gnL/hl+6PcMrXdPLm5f7XdurlifpfE1HZw0dcj YjKg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1714284155; x=1714888955; 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=gaH4W0zCdKof5zfsfQkEntK61qe79URA4z4uMCrQZSs=; b=tubyNBbRcR8qh1qoUDordl2kMHbO3U+o7tECZ2L6ZBlJ1Q7DnthDpbSlMoa519+KU9 uplTy5l65G8vmTRJQsCeOVDly+/MZRDqRywtJLIQGWLpe250qN6pkacPgBI6DRuN9yud rpbd1WT7TIMAz3qtjB5+bc/gY2e81yimYvsPsJy+bJUYtkmZaHwRGKdKVAtPPcIs4TiL AvGUmUz3BzTTC+ZlE/a4rnemn4IL3nZvH3IWI5ewqrdIpvAhcGj2ISKkwIydKu0wxNd1 ws9zgq2IFB5Oq3/9G+r9Vv5fmyVrO4wPALlxQ659kJAtnrl3D8vEazluLTugTJz2i7hd wmLg== X-Gm-Message-State: AOJu0YzfGlxj1T92vUlVP7k0ahHyD+FRy86LZPnpMKhgb5/OJD1EHrj5 QlUiNihpgGZ22/fg4lsnd0geFuzXmYJuIL8aYOQl7GkSKwlScz1udydQN+NI8diWwmzuuhTzCQR XGxMD3zwalCk6Kv7aXLI/qdhvrndmffE7NtN6mA== X-Google-Smtp-Source: AGHT+IGRuK9g/oXkDr62NJwJF7hHpB/NW0O9x4+ye4OoIH0tJYYE++cM7rsJr8IJb5+jo+FZyjA3USJISvevn9zwVWk= X-Received: by 2002:a25:db42:0:b0:dc6:ff12:13d7 with SMTP id g63-20020a25db42000000b00dc6ff1213d7mr6727831ybf.60.1714284154528; Sat, 27 Apr 2024 23:02:34 -0700 (PDT) Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net MIME-Version: 1.0 References: <18c42fdbb30.2831.17a3710df6d58f02ca570cc47e197a63@interi.co> <0f64523d-d949-75ed-682b-789fc33fa3b2@php.net> In-Reply-To: Date: Sun, 28 Apr 2024 15:02:22 +0900 Message-ID: Subject: Re: [PHP-DEV] Proposal: Arbitrary precision native scalar type To: Derick Rethans Cc: internals@lists.php.net Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable From: alex.pravdin@interi.co (Alexander Pravdin) Hello everyone. To continue the discussion, I'm suggesting an updated version of my proposal. The main change is: to use decimal128 as the backend for native decimals, so no 3rd-party libraries are required. Even if adopting a library, it looks like it'll be much easier than the previous proposal. Also, the principle "if any operand is decimal, the result is decimal" is adopted, and conversion requirements are relaxed and more specific. 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 float Native decimals are backed by 128-bit decimals according to IEEE 754-2008. Point to discuss: can we use 128-bit zvals or transpile decimals into a pair of 64-bit zvals representing lo and hi portions? Decimal to float conversion is allowed and smooth: function f (float $value) {} f(0.2); f(0.2d); // allowed with no warnings or errors Function "str_to_decimal" added to convert from string representation of numbers to decimals. Typecast from string to decimal works the same as the "str_to_decimal" func= tion. The function "float_to_decimal" is added to explicitly convert floats to decimals. Internally, it performs explicit float to string conversions using existing defaults and also accepts an optional parameter to define the number of fractional digits to round to. After converting a float to a string, it converts the string to a 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 optimized algorithms are welcome. Explicit type cast "(decimal) float" is the same as using float_to_decimal with defaults. Implicit conversion from float to decimal with type juggling works the same as "float_to_decimal" with defaults but throws a warning to encourage users to use explicit conversion instead: "Implicit float to decimal conversion may cause unexpected results due to possible rounding errors". With strict types, implicit conversion is not possible and generates a TypeError. Literal numbers in the code are compiled to floats by default. If prepended by the "(decimal)" typecast, or the "d" modifier is used (0.2d) the decimal is produced by the compiler without an intermediary float or string. 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. With default_decimal, fractional string literals are compiled into decimals. Without default_decimal: $var =3D 5 / 2; // returns float 2.5 $a =3D 3.02; // compiled to float With default_decimal: $var =3D 5 / 2; // returns decimal 2.5 $a =3D 3.02; // compiled to decimal I understand that this point is controversial, so it can be postponed and decided later. The (decimal) typecast applied to a math operation produces a decimal result without intermediary float by converting all operands to decimals before calculating: $var =3D 5 / 2; // returns float 2.5 $var =3D (decimal)(5 / 2); // returns decimal 2.5 $a =3D 5; $b =3D 2; $var =3D (decimal)($a / $b); // returns decimal 2.5 If any of the math operation operands are decimal, the result is decimal. Floats are converted to decimals with implicit conversion rules mentioned above: Without strict types: $f =3D (float) 0.2; $d =3D (decimal) 0.2; $r =3D $f + $d; // produces a warning about implicit conversion, returns de= cimal $r =3D (decimal)$f + $d; // works with no warnings With strict types: $f =3D (float) 0.2; $d =3D (decimal) 0.2; $r =3D $f + $d; // produces TypeError $r =3D (decimal)$f + $d; // works with no warnings 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 any of the parameters is decimal, they return decimal. Float parameters are converted to decimals implicitly according to the conversion rules mentioned above. I hope this version of the design is closer to being accepted by the community. Please share your thoughts. -- Best, Alexander -- Best regards, Alex Pravdin Interico On Wed, Apr 10, 2024 at 12:55=E2=80=AFAM Alexander Pravdin wrote: > > On Tue, Apr 9, 2024 at 7:52=E2=80=AFPM Derick Rethans wr= ote: > > > Adding a new native type to PHP will create a large change. Not only is > > it "just" adding a new native type, it also means all of the conversion= s > > between types need to be added. This is not a small task. > > I understand this :) > > > > If you want to use arbitrary precision natives, then a precision and > > scale as defined in php.ini defeats the purpose. Every installation can > > then potentially calculate things in a different way. > > > > The only way how to prevent that, is to have *actual* Decimal type, suc= h > > as the Decimal type in MongoDB uses (the IEEE 754 decimal128 type): > > > > - https://www.mongodb.com/docs/mongodb-shell/reference/data-types/#std-= label-shell-type-decimal > > - https://en.wikipedia.org/wiki/Decimal128_floating-point_format > > If PHP core experts think that 128-bit decimal will cover the vast > majority of cases and is worth implementing, I'm totally for it. If we > can implement something standardized then fine. The current thread is > not an RFC candidate, but a kinda discussion board to formulate the > design principles and strategy. > > On another note, is it possible to make zval variable size - 64 or 128 > bits? So the 128-bit decimal can be a struct that will be held in the > stack instead of pointer manipulations. Can it be achieved with the > help of macroses? > > -- > Best, Alexander