From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from elaine.keithp.com (home.keithp.com [63.227.221.253]) by sourceware.org (Postfix) with ESMTPS id 8C97F3857C57 for ; Fri, 28 Aug 2020 03:13:17 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 8C97F3857C57 Received: from localhost (localhost [127.0.0.1]) by elaine.keithp.com (Postfix) with ESMTP id 689C53F2D432; Thu, 27 Aug 2020 20:13:16 -0700 (PDT) X-Virus-Scanned: Debian amavisd-new at keithp.com Received: from elaine.keithp.com ([127.0.0.1]) by localhost (elaine.keithp.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id UxOF0br9Czup; Thu, 27 Aug 2020 20:13:14 -0700 (PDT) Received: from keithp.com (koto.keithp.com [10.0.0.2]) by elaine.keithp.com (Postfix) with ESMTPSA id 63B2C3F2D430; Thu, 27 Aug 2020 20:13:14 -0700 (PDT) Received: by keithp.com (Postfix, from userid 1000) id 3D7CD1582201; Thu, 27 Aug 2020 20:13:14 -0700 (PDT) From: "Keith Packard" To: Brian Inglis , newlib@sourceware.org Subject: Re: Fw: [PATCH 0/3] libm: Clean up gamma functions In-Reply-To: References: <20200826170357.2551683-1-keithp@keithp.com> <87lfhzej39.fsf@keithp.com> Date: Thu, 27 Aug 2020 20:13:13 -0700 Message-ID: <87imd3ea46.fsf@keithp.com> MIME-Version: 1.0 Content-Type: multipart/signed; boundary="=-=-="; micalg=pgp-sha256; protocol="application/pgp-signature" X-Spam-Status: No, score=-5.5 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: newlib@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Newlib mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 28 Aug 2020 03:13:20 -0000 --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Brian Inglis writes: > Last C17 public FDIS N2176 is available via: > > https://web.archive.org/web/20181230041359if_/http://www.open-std.org/jtc= 1/sc22/wg14/www/abq/c17_updated_proposed_fdis.pdf > > see 7.12.8.3 lgamma and 7.12.8.4 tgamma on pp181-182, 7.26 tgmath #5 lgam= ma, > tgamma pp272-273, 7.31.1 complex clgamma, ctgamma p332, F10.5.3 lgamma and > F.10.5.4 tgamma. Thanks for the link -- the difference for lgamma is that in C99: A range error occurs if x is too large. A range error may occur if x is a negative integer or zero. While in C17: A range error occurs if positive x is too large. A pole error may occur if x is a negative integer or zero. Frustratingly, tgamma still returns different errors. In C99: A domain error or range error may occur if x is a negative integer or zero. A range error may occur if the magnitude of x is too large or too small. While in C17: A domain error or pole error may occur if x is a negative integer or zero. A range error occurs if the magnitude of x is too large and may occur if the magnitude of x is too small. C17 appears to have added this new 'pole' error, which seems to match what the IEEE 754 calls a 'divideByZero exception'. Let's see if my understanding of the various errors is correct: IEEE C17 POSIX errno Exception divideByZero Pole Pole ERANGE FE_DIVBYZERO invalid Domain Domain EDOM FE_INVALID overflow Range Range ERANGE FE_OVERFLOW POSIX is more specific than C17, but it does appear to have been updated to follow that spec, including the term 'Pole Error' which wasn't in C99. As my tests all refer to the POSIX spec (which defines the errno/exception values), I think they're correct. Here's the set of values I'm testing for both tgamma and lgamma (I'm not testing gamma currently; we need to sort out what it should be doing first): Value tgamma lgamma POSIX result errno exception POSIX result errno ex= ception +0 Pole +INFINITY ERANGE FE_DIVBYZERO Pole +INFINITY ERANGE FE_= DIVBYZERO =2D0 Pole -INFINITY ERANGE FE_DIVBYZERO Pole +INFINITY ERANGE F= E_DIVBYZERO =2D1 Domain NAN EDOM FE_INVALID Pole +INFINITY ERANGE F= E_DIVBYZERO +3e38f Range +INFINITY ERANGE FE_OVERFLOW Range +INFINITY ERANGE FE_= OVERFLOW +1.7e308 Range +INFINITY ERANGE FE_OVERFLOW Range +INFINITY ERANGE FE_= OVERFLOW =2D3e38f Domain NAN EDOM FE_INVALID Pole +INFINITY ERANGE F= E_DIVBYZERO =2D1.7e308 Domain NAN EDOM FE_INVALID Pole +INFINITY ERANGE F= E_DIVBYZERO +inf None +INFINITY 0 0 None +INFINITY 0 0 =2Dinf Domain NAN EDOM FE_INVALID None +INFINITY 0 0 I have rationalized the differences in this way: Domain error means there is no defined limit for the function approaching the parameter. Pole error means that there *is* a defined limit in this case. For non-positive inputs, the limit of the value of the tgamma function depends on whether that limit is approached from above or below. For zero, we can separate out 'approach from below' and 'approach from above' with the sign -- -0 might well be the result of an underflow from below, hence returning the value of the function as approached from below makes "sense", in this case -INFINITY. Similarly, +0 might well be underflow from above, so the function can return +INFINITY. In both cases, as the limit is well defined, this represents a Pole error rather than a Domain error, hence the differences in errno and exceptions. =20=20=20=20=20=20=20=20 For negative integers, as the limit depends on whether the value is approached from below or above and we have no way of distinguishing these two cases from the input, the limit is not well defined, so we have a Domain error and return NAN/EDOM/FE_INVALID. For the lgamma function, the limit for non-positive integers is always +INFINITY because it returns ln(|=CE=93(x)|). This makes it well defined and hence a Pole error rather than a Domain error Huge negative values (-1e308) are negative integers, and hence treated that way, generating a Domain error for tgamma and Range error for lgamma +INFINITY input and +INFINITY output generate *no* error presumably because there's an assumption that the computation which resulted in +INFINITY being provided to these functions already raised a FE_OVERFLOW exception, and perhaps an ERANGE errno. Please review the table above to see if you agree about what errno and exception values each of the provided inputs should generate. I'd really like to know if you can suggest additional test cases to use to validate the correctness of these functions. =2D-=20 =2Dkeith --=-=-= Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iQIzBAEBCAAdFiEEw4O3eCVWE9/bQJ2R2yIaaQAAABEFAl9IdkkACgkQ2yIaaQAA ABEILA//RSm4onnIV6bjSakVmR3jajURVVv0cO1vuqi7k1yud3tHjLYSOqdB702Z n7kj05BHd+GNPHdG7SEZaaoYBTDZUIsXu9VCTp5+7m/hoc41zwDb4oaJWo3GoE9H S6OmP8b7inRbEO/wTDhNK1YfWZpkELbfo+uGZdpiAaDTVJ3yPlkxj8wn4CsIO/z7 VvZOackeTdt0BdMQZk2azESqrQdM6+w+i03gmm8IfptjJO9SvvgsHUG+KORTOo3h QW5LXZQBiBy3rmabE5t9IqBojemPhhHnBwmLJ2/9wvRbjmosLA1ZlRo4Xz0HgabP Y1kjbbEBI3ojxyu3X0FWQWnUHezlF5O6MhLDWoEfDILnl5pQ7FBrpEvkTKN6h75U jACBToLldp79R7W17V9vxfdBtMZDAAWCa8jYKSZWR04CvWcxuWliXSX6JmNFPbDO 4y6GydkbWs/fw3azGgX9ngAHjtfN8hi+uvtz8EXjIm0hSRC/bwsF0MjkFhehjSD2 UJ4t9L4tkqCmFCbn3inJwFlq8fZGSvQBkbiP0LwYghigwk8zIgn0wo4AfejoSUhY lhg5udh7VcJwprJi9atqPClPvlVZXHHaxaxQVBdZCN7SG5fzL5AfIWLRhiFjAk1I FyKaX7tnpyMHTbPzcarQTYOo+/X5xl/UBKhAd8D4xpXgxnGeoB4= =XV4S -----END PGP SIGNATURE----- --=-=-=--