public inbox for newlib@sourceware.org
 help / color / mirror / Atom feed
From: "Keith Packard" <keithp@keithp.com>
To: Brian Inglis <Brian.Inglis@SystematicSw.ab.ca>, newlib@sourceware.org
Subject: Re: Fw: [PATCH 0/3] libm: Clean up gamma functions
Date: Thu, 27 Aug 2020 20:13:13 -0700	[thread overview]
Message-ID: <87imd3ea46.fsf@keithp.com> (raw)
In-Reply-To: <a0515976-fd8c-ca20-78c6-594a1f8688b8@SystematicSw.ab.ca>

[-- Attachment #1: Type: text/plain, Size: 5218 bytes --]

Brian Inglis <Brian.Inglis@SystematicSw.ab.ca> writes:

> Last C17 public FDIS N2176 is available via:
>
> https://web.archive.org/web/20181230041359if_/http://www.open-std.org/jtc1/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 lgamma,
> 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   exception

+0       Pole   +INFINITY ERANGE FE_DIVBYZERO   Pole   +INFINITY ERANGE FE_DIVBYZERO
-0       Pole   -INFINITY ERANGE FE_DIVBYZERO   Pole   +INFINITY ERANGE FE_DIVBYZERO
-1       Domain    NAN    EDOM   FE_INVALID     Pole   +INFINITY ERANGE FE_DIVBYZERO
+3e38f   Range  +INFINITY ERANGE FE_OVERFLOW    Range  +INFINITY ERANGE FE_OVERFLOW
+1.7e308 Range  +INFINITY ERANGE FE_OVERFLOW    Range  +INFINITY ERANGE FE_OVERFLOW
-3e38f   Domain    NAN    EDOM   FE_INVALID     Pole   +INFINITY ERANGE FE_DIVBYZERO
-1.7e308 Domain    NAN    EDOM   FE_INVALID     Pole   +INFINITY ERANGE FE_DIVBYZERO
+inf     None   +INFINITY 0      0              None   +INFINITY 0      0
-inf     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.
        
        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(|Γ(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.

-- 
-keith

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]

  reply	other threads:[~2020-08-28  3:13 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-08-26 17:03 Keith Packard
2020-08-26 17:03 ` [PATCH 1/3] libm: Fix sign value returned from __ieee754_lgamma*_r(-0) Keith Packard
2020-08-26 17:03 ` [PATCH 2/3] libm: Remove __ieee754_gamma_r variants Keith Packard
2020-08-26 18:20   ` Corinna Vinschen
2020-08-26 19:10     ` Keith Packard
2020-08-27  7:24       ` Corinna Vinschen
2020-08-27 17:05         ` Keith Packard
2020-08-28  8:19           ` Corinna Vinschen
2020-08-28  8:34             ` Corinna Vinschen
2020-09-01 16:33               ` Fabian Schriever
2020-09-01 17:23                 ` Keith Packard
2020-09-02  8:03                   ` Corinna Vinschen
2020-09-02 20:37                     ` Keith Packard
2020-09-03  8:04                       ` Corinna Vinschen
2020-09-03 15:59                         ` Brian Inglis
2020-09-03 21:25                           ` Keith Packard
2020-09-03 22:09                             ` Brian Inglis
2020-09-04  0:01                               ` Keith Packard
2020-09-04  0:27                                 ` Brian Inglis
2020-09-04  1:37                                   ` Keith Packard
2020-09-04 13:03                                     ` Corinna Vinschen
2020-09-04 16:19                                       ` Keith Packard
2020-08-26 17:03 ` [PATCH 3/3] libm: Adjust errno/exception values for gamma/lgamma Keith Packard
     [not found]   ` <SN5P110MB0383012287522E8285674CAB9A550@SN5P110MB0383.NAMP110.PROD.OUTLOOK.COM>
2020-08-27 17:55     ` Fw: " C Howland
2020-08-27 19:28       ` Brian Inglis
     [not found] ` <SN5P110MB0383186ECD9B028A4B0E2ECC9A550@SN5P110MB0383.NAMP110.PROD.OUTLOOK.COM>
2020-08-27 17:43   ` Fw: [PATCH 0/3] libm: Clean up gamma functions C Howland
2020-08-27 23:59     ` Keith Packard
2020-08-28  2:03       ` Brian Inglis
2020-08-28  3:13         ` Keith Packard [this message]
2020-08-28  3:51           ` Brian Inglis
2020-08-28 17:13             ` Keith Packard
2020-08-28 18:29           ` Joseph Myers
2020-08-28 19:32             ` Keith Packard
2020-08-28 19:53               ` Joseph Myers

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87imd3ea46.fsf@keithp.com \
    --to=keithp@keithp.com \
    --cc=Brian.Inglis@SystematicSw.ab.ca \
    --cc=newlib@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).