Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:122832 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 6DC881A009C for ; Sun, 31 Mar 2024 00:09:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1711843804; bh=cBwM3jbFli523b2QHIRp7E/UQbTokP6vO57qKxe1/MM=; h=Subject:From:In-Reply-To:Date:Cc:References:To:From; b=lTiQxToCAk7pmuINsJtMk3LsbiUzEkGPEzTcbA4d+KCwy+YqOXKmZPTY3ox2eS5PI TDj4VfveDEslBEC0R7C+yu+TERNx0wtXpo0udM3VwX6j/Hdua0WQrNpf1t1AhwcrnF Nl5IuZ6/AqOV5XbW8orgl6/CIU9xaCAUQNIOZTdQwDxsfmp0kQJp3vYkg4HLVKFohv QVdGAl66wa2R4YvehZhisOHHEcFeZbugwBMBSg1hCHEFbbrCKDHaYVLNvjjgB+k5Th sXHxoUbJPvqZYaVUjvIgysCMvgjVkH2XoAQkOPJdAufVLtKcewNbib0dSISgF74p6E 3w0UQpyS2yfTQ== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 89920180078 for ; Sun, 31 Mar 2024 00:10:02 +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,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.sakiot.com (mail.sakiot.com [160.16.227.216]) (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, 31 Mar 2024 00:10:01 +0000 (UTC) Received: from smtpclient.apple (unknown [117.55.37.250]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.sakiot.com (Postfix) with ESMTPSA id 748A0401D9; Sun, 31 Mar 2024 09:09:32 +0900 (JST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=sakiot.com; s=default; t=1711843772; bh=cBwM3jbFli523b2QHIRp7E/UQbTokP6vO57qKxe1/MM=; h=Subject:From:In-Reply-To:Date:Cc:References:To:From; b=e/VD9ZOxR6pJeD0LM2v13z6TUbDaBbhcv0K/rg4L6TnzQILCF2vP2xs1Ct/TL8veo rDGtfgz3tNQrkdOGfLAOLR99rRRKk/6pxG+CohIiNtGxqBhisS2JR4+4Sgib4XTwOE tonP5DmaXqeQefePJe6LaC91amdF82oxjdmw0RXU= Content-Type: text/plain; charset=utf-8 Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net Mime-Version: 1.0 (Mac OS X Mail 16.0 \(3731.700.6\)) Subject: Re: [PHP-DEV] [RFC] [Discussion] Support object type in BCMath In-Reply-To: Date: Sun, 31 Mar 2024 09:09:18 +0900 Cc: Aleksander Machniak , php internals Content-Transfer-Encoding: quoted-printable Message-ID: References: <4F094EDA-5058-407D-AF39-06FD934FDE1F@sakiot.com> <68CF373E-6ABF-4471-8992-813B4BA1B508@sakiot.com> <904197f4-afb5-401e-9e17-7a655c5449d0@alec.pl> To: Jordan LeDoux X-Mailer: Apple Mail (2.3731.700.6) From: saki@sakiot.com (Saki Takamachi) Hi Jordan, > For addition, it absolutely should expand scale like this, unless the = constructor also defines a default rounding type that is used in that = situation. All numbers, while arbitrary, will be finite, so addition = will always be exact and known based on inputs prior to calculation.=20 >=20 > Treating scale like this isn't more strict, it's confusing. For = instance: >=20 > ``` > $numA =3D new Number('1.23', 2); > $numB =3D new Number('1.23456', 5); >=20 > $expandedScale1 =3D $numA + $numB; // 2.46456 > $expandedScale2 =3D $numB + $numA; // 2.46456 >=20 > $strictScale1 =3D $numA + $numB; // 2.46 assuming truncation > $strictScale2 =3D $numB + $numA; // 2.46456 > ``` >=20 > I ran into this same issue with operand ordering when I was writing my = operator overload RFC. >=20 > There are ways you could do the overload implementation that would get = around this for object + object operations, but it's also mathematically = unsound and probably unexpected for anyone who is going to the trouble = of using an arbitrary precision library. >=20 > Addition and subtraction should automatically use the largest scale = from all operands. Division and multiplication should require a = specified scale. >=20 > Because of this, I'm not entirely sure that specifying a scale in the = constructor is actually a good thing. It is incredibly easy to create = situations, unless the implementation in C is VERY careful, where the = operand positions matter beyond the simple calculation. Multiplication = is commutative, but division is not. This would almost certainly lead to = some very difficult to track down bugs. >=20 > Putting scale in the constructor is similar to some of the examples of = "possible misuse cases of operator overloading" that I had to go over = when I was making my RFC. We definitely want to avoid that if possible = for the first number/math object that has operator overloads. Your opinion may be reasonable given the original BCMath calculation = order. That is, do you intend code like this? Signature: ``` // public function __construct(string|int $number) // public function getNumber(?int $scale =3D null): string ``` Add: ``` // public function add(Number|string|int $number): string $num =3D new Number('1.23456'); $num2 =3D new Number('1.23'); $add =3D $num + $num2; $add->getNumber(); // '2.46456' $add->getNumber(1); // =E2=80=982.4' $add =3D $num->add($num2); $add->getNumber(); // '2.46456' $add->getNumber(1); // '2.4' ``` Div: ``` // public function div(Number|string|int $number, int = $scaleExpansionLimit =3D 10): string // case 1 $num =3D new Number('0.0001'); $num2 =3D new Number('3'); $div =3D $num / $num2; // scale expansion limit is always 10 $div->getNumber(); // '0.0000333333333' $div =3D $num->div($num2, 20); $div->getNumber(); // '0.00003333333333333333333' $div->getNumber(7); // =E2=80=980.0000333' // case 2 $num =3D new Number('1.111111'); $num2 =3D new Number('3'); $div =3D $num->div($num2, 3); $div->getNumber(); // '0.370' $div->getNumber(7); // =E2=80=980.3700000' ``` Since the scale can be inferred for everything other than div, a special = argument is given only for div. Regards. Saki=