Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:123077 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 E51F71A009C for ; Tue, 9 Apr 2024 23:36:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1712705829; bh=Jr/CjCZJcLor8VUWz1WZwcZBxX2ko/5KY+G4P9GV9Rk=; h=From:Subject:Date:References:Cc:In-Reply-To:To:From; b=lwcliysrxQyWJ/sFeCIarTgD7kVJFXalSXY9odrY4jKO00LguWyr6n1EfezVaOtBg fCxqVW+5fTj/KNt+Pvct86kT65drCUWjMJWYniYHIqKx682SEdMze+HW038wzxkTet lLnFEpEsB/SM6uP5klCtguVd4zxBzZj+hYilJDPFG6i9krpz/DJmhqIqA5+Bvx8C8r POHQkWRTsAocOfA5otRAtjwYyYr9PdeU7jNCruxY9ez7YhRCnR9OKlvzpn/B/a5Fcx ALPGFt8xXpbfNX3sLQn4Og5nadHvuhp5jdjhjlIZLYxxHEF2MoOKY/fIAPxle6mYUr WMETAElSn3coA== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 2AE8818057B for ; Tue, 9 Apr 2024 23:37:09 +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,HTML_MESSAGE, 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 ; Tue, 9 Apr 2024 23:37:08 +0000 (UTC) Received: from smtpclient.apple (32.12.156.220.rev.vmobile.jp [220.156.12.32]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by mail.sakiot.com (Postfix) with ESMTPSA id 7E794401EE; Wed, 10 Apr 2024 08:36:34 +0900 (JST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=sakiot.com; s=default; t=1712705794; bh=Jr/CjCZJcLor8VUWz1WZwcZBxX2ko/5KY+G4P9GV9Rk=; h=From:Subject:Date:References:Cc:In-Reply-To:To:From; b=wP6LGTY/CgMMJPGVEJYsNAu4s9xGt+7abFUrTSgCyjJCltBBoGzrIEEnMrahbTQAL kghxSd5POhMLLmvSNu9W3OvIPXAE6/St0biCczgi9C6CzCx6kTgMdQ5Z+86UT8TtyT bQNv+OVQFW62nDPhGZgJhFv+yUsEXMfuwmaji728= Content-Type: multipart/alternative; boundary=Apple-Mail-61C39246-93D5-47AE-AF20-34A19094A130 Content-Transfer-Encoding: 7bit Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net Mime-Version: 1.0 (1.0) Subject: Re: [PHP-DEV] [RFC] [Discussion] Support object type in BCMath Date: Wed, 10 Apr 2024 08:36:21 +0900 Message-ID: References: <6628b5e3-5f4b-4c9c-a940-56f72a645af1@rwec.co.uk> Cc: internals@lists.php.net In-Reply-To: <6628b5e3-5f4b-4c9c-a940-56f72a645af1@rwec.co.uk> To: "Rowan Tommins [IMSoP]" X-Mailer: iPhone Mail (21D61) From: saki@sakiot.com (Saki Takamachi) --Apple-Mail-61C39246-93D5-47AE-AF20-34A19094A130 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: quoted-printable Hi Rowan, a). > I propose: >=20 > - The constructor accepts string|int $num only. >=20 > - All operations accept an optional scale and rounding mode. >=20 > - If no rounding mode is provided, the default behaviour is to truncate. T= his means that (new BCMath\Number('20'))->div(3, 5) has the same result as b= cdiv('20', '3', 5) which is 6.66666 >=20 > - If a rounding mode is provided, the object transparently calculates one e= xtra digit of scale, then rounds according to the specified mode. >=20 > - If no scale is provided, most operations will automatically calculate th= e required scale, e.g. add will use the larger of the two scales. This is th= e same as the current RFC. >=20 > - If no scale is provided to div(), sqrt(), or pow(-$x), the result will b= e calculated to the scale of the left-hand operand, plus 10. This is the def= ault behaviour in the current RFC. >=20 > - Operator overloads behave the same as not specifying a scale or rounding= mode to the corresponding method. Therefore (new BCMath\Number('20')) / (ne= w BCMath\Number('3')) will result in 6.6666666666 - an automatic scale of 10= , and truncation of further digits. >=20 >=20 >=20 > Compared to the current RFC, that means: >=20 > - Remove the ability to customise "max expansion scale". For most users, t= his is a technical detail which is more confusing than useful. Users in grou= p (b) will never encounter it, because they will specify scale manually; adv= anced users in group (a) may want to customise the logic in different ways a= nyway. >=20 > - Remove the ability for a Number value to carry around its own default ro= unding mode. Users in group (a) will never use it. Users in group (b) are li= kely to want the same rounding in the whole application, but providing it on= every call to new Number() is no easier than providing it on each fixed-sca= le calculation. >=20 > - Remove the $maxExpansionScale and $roundingMode properties and construct= or parameters. >=20 > - Remove withMaxExpansionScale and withRoundMode. >=20 > - Remove all the logic around propagating rounding mode and expansion scal= e between objects. >=20 I have two questions. - The scale and rounding mode are not required for example in add, since the= scale of the result will never be infinite and we can automatically calcula= te the scale needed to fit the result. Does adding those two options to all c= alculations mean adding them to calculations like add as well? - As Tim mentioned, it may be confusing to have an initial value separate fr= om the mode of the `round()` method. Would it make sense to have an initial v= alue of HALF_UP? > I've also noticed that the round method is currently defined as: >=20 > - public function round(int $precision =3D 0, int $mode =3D PHP_ROUND_HALF_= UP): Number {} >=20 > Presumably $precision here is actually the desired scale of the result? If= so, it should probably be named $scale, as in the rest of the interface.=20= >=20 > I realise it's called $precision in the global round() function; that's pr= esumably a mistake which is now hard to fix due to named parameters. >=20 > Ideally, it would be nice to have both roundToPrecision() and roundToScale= (), but as Jordan explained, an implementation which actually calculated pre= cision could be difficult and slow. >=20 There is good news about this. The RFC for `bcround` does not specify the ar= gument names, and the implementer (me) has decided on the argument names. And it's a change that hasn't even been merged into master yet, so I can cha= nge the argument name without any BC break. Regards. Saki= --Apple-Mail-61C39246-93D5-47AE-AF20-34A19094A130 Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: 7bit
Hi Rowan,
a).

I propose:

- The constructor accepts string|int $num only.

- All operations accept an optional scale and rounding mode.

- If no rounding mode is provided, the default behaviour is to truncate. This means that (new BCMath\Number('20'))->div(3, 5) has the same result as bcdiv('20', '3', 5) which is 6.66666

- If a rounding mode is provided, the object transparently calculates one extra digit of scale, then rounds according to the specified mode.

- If no scale is provided, most operations will automatically calculate the required scale, e.g. add will use the larger of the two scales. This is the same as the current RFC.

- If no scale is provided to div(), sqrt(), or pow(-$x), the result will be calculated to the scale of the left-hand operand, plus 10. This is the default behaviour in the current RFC.

- Operator overloads behave the same as not specifying a scale or rounding mode to the corresponding method. Therefore (new BCMath\Number('20')) / (new BCMath\Number('3')) will result in 6.6666666666 - an automatic scale of 10, and truncation of further digits.

Compared to the current RFC, that means:

- Remove the ability to customise "max expansion scale". For most users, this is a technical detail which is more confusing than useful. Users in group (b) will never encounter it, because they will specify scale manually; advanced users in group (a) may want to customise the logic in different ways anyway.

- Remove the ability for a Number value to carry around its own default rounding mode. Users in group (a) will never use it. Users in group (b) are likely to want the same rounding in the whole application, but providing it on every call to new Number() is no easier than providing it on each fixed-scale calculation.

- Remove the $maxExpansionScale and $roundingMode properties and constructor parameters.

- Remove withMaxExpansionScale and withRoundMode.

- Remove all the logic around propagating rounding mode and expansion scale between objects.


I have two questions.
- The scale and rounding mode are not required for example in add, since the scale of the result will never be infinite and we can automatically calculate the scale needed to fit the result. Does adding those two options to all calculations mean adding them to calculations like add as well?
- As Tim mentioned, it may be confusing to have an initial value separate from the mode of the `round()` method. Would it make sense to have an initial value of HALF_UP?

I've also noticed that the round method is currently defined as:

- public function round(int $precision = 0, int $mode = PHP_ROUND_HALF_UP): Number {}

Presumably $precision here is actually the desired scale of the result? If so, it should probably be named $scale, as in the rest of the interface.

I realise it's called $precision in the global round() function; that's presumably a mistake which is now hard to fix due to named parameters.

Ideally, it would be nice to have both roundToPrecision() and roundToScale(), but as Jordan explained, an implementation which actually calculated precision could be difficult and slow.

There is good news about this. The RFC for `bcround` does not specify the argument names, and the implementer (me) has decided on the argument names.
And it's a change that hasn't even been merged into master yet, so I can change the argument name without any BC break.

Regards.

Saki
--Apple-Mail-61C39246-93D5-47AE-AF20-34A19094A130--