Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:122952 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 D178D1A009D for ; Thu, 4 Apr 2024 22:31:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1712269945; bh=3fRB29OaxZMUChzAlRxJ9+6Drc1z2vZVE5OmQ7oqh7U=; h=References:In-Reply-To:From:Date:Subject:To:Cc:From; b=kAoklAOXPZGccADayzbnvwZh+b6UwuS9rr+nPeUmVXv/6x8To7jpzVKMLpsHX+hFv kzOW3ysFRX7SYX/kJBd+1adSe+M4zB0Koge8rs/jlsq3HKrtWjwjTUFQF4ruDt2a52 uGQorfmr+Kj9Pro6NSLdT5SEaLOyKyfg+2niJ32Mr5Y6/fOBsI83zoGsaJOx+pds0G r+51qnJ6jGe2EfdmQPInGcAmydSI3Fy5g/KVs0Bfm+qv3VDWeTUnvtapnJsKIyU1dk 6FeDGrH2xnoXfUYonGq1WfrqlZFlRDxfucHOaK7n/5X3a6heb/g3++KNeTyppMKS5J EcukS94bO5rkA== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 4F7DF18078A for ; Thu, 4 Apr 2024 22:32:22 +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.6 required=5.0 tests=BAYES_50,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_PASS,FREEMAIL_FROM, HTML_MESSAGE,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=4.0.0 X-Spam-Virus: No X-Envelope-From: Received: from mail-pj1-f48.google.com (mail-pj1-f48.google.com [209.85.216.48]) (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 ; Thu, 4 Apr 2024 22:32:19 +0000 (UTC) Received: by mail-pj1-f48.google.com with SMTP id 98e67ed59e1d1-29e0a1fd9a7so1034968a91.2 for ; Thu, 04 Apr 2024 15:31:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1712269909; x=1712874709; darn=lists.php.net; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=3fRB29OaxZMUChzAlRxJ9+6Drc1z2vZVE5OmQ7oqh7U=; b=UMOdlF+8CPFHB5PClK99yUdxmf33x6GoEMbb09wgAxAQ7qvfBQZd4lOwAWXLmQaDuj Bhnm4RMUwC8v5SUbMcqaj0sqXoVDXiPMfAreshx2OTgKF+EpfyOpo1cmNCQd6+8kAe65 kqDjPHQ4eHzTP4kuLd+HiL88AHQPBPq7DP+O17qYChA5u6c/L2035Dh1JgzeNkzQF8Rm OGZpXihKIR1+50f8zeE2tW04b77pjqH3xiXFD2mxQonavwz8/EQNu9d59HiiYlMJqe57 rtCWOE2bkoKXJ4TAuKvCsuPGYQ70ZvwCybqnI9xPrwgpSkbwy3S9DO8PJI89OTAtlhzo 3LKw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1712269909; x=1712874709; h=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=3fRB29OaxZMUChzAlRxJ9+6Drc1z2vZVE5OmQ7oqh7U=; b=mErwMiTG0NV2jbIOcI8kbEIi9A2ixr8cOB8uVw79WCJUe/m+9ji+iU3yxjCcAJ1baE CsbXs+NujKQnOB+5JjN6XRWdFbKdLvxe5R4cLM83t+tQs3ltfMO1Gs77fk8ItwfuPH5N 3lajVlZ03Ryah318xTjEfJhjFzgV1ZGaku6fiybk9psFG/h51/7LD65TW0mEkrUWN4pg cQzTF+X/cdbqWC+s+99MhZWZKQ02/xU4oIAqVqq7aLYu2nKMjm+ItWK9TrGyPkAmiQNB NX8HtXn+E4Iet5G0nT+C+PTTUtPNFIB15EkfCbDYKGgBI0zYt5yGGXfrk1+cX/PtQ+g4 iAqA== X-Gm-Message-State: AOJu0YwD8ZBvwfShbKhwUZ7TfEbPzwHEjzUFKj3jEtyqqz6jtHjOZBmy XlSSVJ43WqJcy7OaJNyeoAeAZ/4wDQYMrUQpJDIexalnbL4ZW4LfkUfkycHQb6P88tzFx4N/WAi QgZWtMpImJgRW8iHkigWrs7zq3CWA3m+H X-Google-Smtp-Source: AGHT+IFupinTn9yuMepSS66gwtWt+Ut0SE6w1letCUNAyRBfAYWpE/ZWbov8eUpW5Ue8QQQIeeJhkBUB5PRzM1sOVJk= X-Received: by 2002:a17:90b:4f47:b0:2a2:f06a:4fea with SMTP id pj7-20020a17090b4f4700b002a2f06a4feamr1893515pjb.27.1712269908988; Thu, 04 Apr 2024 15:31:48 -0700 (PDT) Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net MIME-Version: 1.0 References: <18c42fdbb30.2831.17a3710df6d58f02ca570cc47e197a63@interi.co> <9dfdd88a-f840-4933-b26b-8149a4381246@rwec.co.uk> In-Reply-To: <9dfdd88a-f840-4933-b26b-8149a4381246@rwec.co.uk> Date: Thu, 4 Apr 2024 15:31:33 -0700 Message-ID: Subject: Re: [PHP-DEV] Proposal: Arbitrary precision native scalar type To: "Rowan Tommins [IMSoP]" Cc: internals@lists.php.net Content-Type: multipart/alternative; boundary="000000000000af5aa006154ce7b6" From: jordan.ledoux@gmail.com (Jordan LeDoux) --000000000000af5aa006154ce7b6 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Thu, Apr 4, 2024 at 2:28=E2=80=AFPM Rowan Tommins [IMSoP] wrote: > > > I haven't followed the discussion in the other thread, but I'm not sure > what the use case would be for a "fixed scale decimal" that followed > those rules. > > As mentioned before, the use case I've encountered is money > calculations, where what people want to fix is the smallest unit of > account - e.g. =E2=82=AC0.01 for practical currency, or =E2=82=AC0.0001 f= or detailed > accounting / trading. > > If I write $total =3D 1.03_d2; $perPerson =3D $total / 2; I want a result= of > 0.51_d2 or 0.52_d2 - that's why I specified a scale of 2 in the first > place. > Well, firstly most of the financial applications that I've worked in (I work for a firm that writes accounting software right now) do not calculate intermediate steps like this with fixed precision, or even have an interest in doing so. They generally want maximum precision that is computationally reasonable, and then round it according to their preferred method at the end. Doing the calculations as you are suggesting would introduce a maximum error of several cents/pence/etc. after only two or three calculations, which is utterly useless for most applications that deal with money. Truly "fixed-precision" is not something that decimal should even try to be, in my opinion. The use cases where you CANNOT simply round the result at the end to fit your display output or your storage location are very minimal. > If I want an accurate result of 0.515_d3, I would just specify 1.03_d, > since the scale hasn't had any effect on the result. > > If I want a lossless split into [0.51_d2, 0.52_d2] I still need a > function to exist somewhere, whether you spell that $total->split(2), or > decimal_split($total, 2), etc. So it seems safer to also have > $total->div(2, Round::DOWN) or decimal_div($total, 2, Round::DOWN) and > have $total / 2 give an error. > I mean, what you are describing is how such OBJECTS are designed in other languages like Python, but not scalars. Python also has (almost completely unrestricted) userland operator overloading, which PHP does not, which further makes the comparison a little murky. This kind of precision restriction isn't something you would place on an individual value, it's something you would place on all calculations. That's why in Python this is done with a global runtime setting using `getContext().perc` and `getContext().rounding`. A particular value having a precision of X doesn't imply anything concrete about a calculation that uses that value necessarily. > Possibly, it could only error if the result doesn't fit in the scale, so > that this would be fine: $total =3D 11.00_d2; $perPerson =3D $total / 2; > assert($perPerson =3D=3D=3D 5.50_d2) > > Or possibly, it would just be an error to perform division on a fixed > scale decimal, but allowed on a variable-fixed scale decimal. > Maybe we're just not understanding each other. Are you opposed to the idea of doing this as a scalar? It certainly feels that way. This feels more like an argument in favor of doing object-like numerics for this. I suppose that isn't really that strange either, because as I noted such a value will almost certainly need to be refcounted because it will not fit into the 64 bits available for a zval no matter what underlying library is used to perform the math. Jordan --000000000000af5aa006154ce7b6 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable


=
On Thu, Apr 4, 2024 at 2:28=E2=80=AFP= M Rowan Tommins [IMSoP] <imsop.p= hp@rwec.co.uk> wrote:


I haven't followed the discussion in the other thread, but I'm not = sure
what the use case would be for a "fixed scale decimal" that follo= wed
those rules.

As mentioned before, the use case I've encountered is money
calculations, where what people want to fix is the smallest unit of
account - e.g. =E2=82=AC0.01 for practical currency, or =E2=82=AC0.0001 for= detailed
accounting / trading.

If I write $total =3D 1.03_d2; $perPerson =3D $total / 2; I want a result o= f
0.51_d2 or 0.52_d2 - that's why I specified a scale of 2 in the first p= lace.

Well, firstly most of the financi= al applications that I've worked in (I work for a firm that writes acco= unting software right now) do not calculate intermediate steps like this wi= th fixed precision, or even have an interest in doing so. They generally wa= nt maximum precision that is computationally reasonable, and then round it = according to their preferred method at the end. Doing the calculations as y= ou are suggesting would introduce a maximum error of several cents/pence/et= c. after only two or three calculations, which is utterly useless for most = applications that deal with money.

Truly "fix= ed-precision" is not something that decimal should even try to be, in = my opinion. The use cases where you CANNOT simply round the result at the e= nd to fit your display output or your storage location are very minimal.
=C2=A0
If I want an accurate result of 0.515_d3, I would just specify 1.03_d,
since the scale hasn't had any effect on the result.

If I want a lossless split into [0.51_d2, 0.52_d2] I still need a
function to exist somewhere, whether you spell that $total->split(2), or=
decimal_split($total, 2), etc. So it seems safer to also have
$total->div(2, Round::DOWN) or decimal_div($total, 2, Round::DOWN) and <= br> have $total / 2 give an error.

I mean, = what you are describing is how such OBJECTS are designed in other languages= like Python, but not scalars. Python also has (almost completely unrestric= ted) userland operator overloading, which PHP does not, which further makes= the comparison a little murky.

This kind of preci= sion restriction isn't something you would place on an individual value= , it's something you would place on all calculations. That's why in= Python this is done with a global runtime setting using `getContext().perc= ` and `getContext().rounding`. A particular value having a precision of X d= oesn't imply anything concrete about a calculation that uses that value= necessarily.
=C2=A0
Possibly, it could only error if the result doesn't fit in the scale, s= o
that this would be fine: $total =3D 11.00_d2; $perPerson =3D $total / 2; assert($perPerson =3D=3D=3D 5.50_d2)

Or possibly, it would just be an error to perform division on a fixed
scale decimal, but allowed on a variable-fixed scale decimal.

Maybe we're just not understanding each other. A= re you opposed to the idea of doing this as a scalar? It certainly feels th= at way. This feels more like an argument in favor of doing object-like nume= rics for this. I suppose that isn't really that strange either, because= as I noted such a value will almost certainly need to be refcounted becaus= e it will not fit into the 64 bits available for a zval no matter what unde= rlying library is used to perform the math.

J= ordan
--000000000000af5aa006154ce7b6--