]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/commit
Fix tgamma() on some special args:
authorbde <bde@FreeBSD.org>
Wed, 2 May 2007 15:24:49 +0000 (15:24 +0000)
committerbde <bde@FreeBSD.org>
Wed, 2 May 2007 15:24:49 +0000 (15:24 +0000)
commitf9978195dcf7995705c06b7f08567ba6ddcaed8f
tree1b4dfe607c9ba9f340aef50d582778c8219ed5c5
parent98484906b64f28e7d3ec42156666cd1efd6b9998
Fix tgamma() on some special args:
(1) tgamma(-Inf) returned +Inf and failed to raise any exception, but
    should always have raised an exception, and should behave like
    tgamma(negative integer).
(2) tgamma(negative integer) returned +Inf and raised divide-by-zero,
    but should return NaN and raise "invalid" on any IEEEish system.
(3) About half of the 2**52 negative intgers between -2**53 and -2**52
    were misclassified as non-integers by using floor(x + 0.5) to round
    to nearest, so tgamma(x) was wrong (+-0 instead of +Inf and now NaN)
    on these args.  The floor() expression is hard to use since rounding
    of (x + 0.5) may give x or x + 1, depending on |x| and the current
    rounding mode.  The fixed version uses ceil(x) to classify x before
    operating on x and ends up being more efficient since ceil(x) is
    needed anyway.
(4) On at least the problematic args in (3), tgamma() raised a spurious
    inexact.
(5) tgamma(large positive) raised divide-by-zero but should raise overflow.
(6) tgamma(+Inf) raised divide-by-zero but should not raise any exception.
(7) Raise inexact for tiny |x| in a way that has some chance of not being
    optimized away.

The fix for (5) and (6), and probably for (2), also prevents -O optimizing
away the exception.

PR: 112180 (2)
Standards: Annex F in C99 (IEC 60559 binding) requires (1), (2) and (6).
lib/msun/bsdsrc/b_tgamma.c