(glibc 2.8) When expm1(x) is given a large negative x value (e.g., in the range -1e5 through to -1e308), it correctly returns -1. However, it also raises an underflow exception. This is bogus. The result has not underflowed: the result is asymptotically close to 1 (not zero).
Created attachment 2843 [details] test program Example runs showing problem: $ /tmp/mt_expm1 -- -1e5 errno == 0 fetestexcept() says: FE_UNDERFLOW FE_INEXACT expm1(-1.00000000000000000e+05)=-1.00000000000000000e+00 0 FE_UNDERFLOW normal $ /tmp/mt_expm1 -- -1e308 errno == 0 fetestexcept() says: FE_UNDERFLOW FE_INEXACT expm1(-1.00000000000000001e+308)=-1.00000000000000000e+00 0 FE_UNDERFLOW normal
Confirmed on x86 with current sources. Does not appear on x86_64. This is a quality-of-implementation issue only, since C99 and C11 permit spurious underflow exceptions (as well as spurious inexact exceptions, and raising inexact even when the result is exact).
Fixed for 2.17 by: commit f17ac40d7cb8e8c462476b6ab703262f6b8f6da8 Author: Joseph Myers <joseph@codesourcery.com> Date: Fri Jul 6 11:17:41 2012 +0000 Fix expm1 spurious underflow exceptions (bug 6778).
Fix documented for man-pages-5.07. commit 4f16aab8244518d9f46fb6e8d4dc8e6e73266771 Author: Michael Kerrisk <mtk.manpages@gmail.com> Date: Sat May 23 11:45:36 2020 +0200 expm1.3: The expm1() bogus underflow floating-point exception has been fixed Fixed in glibc 2.17. See https://www.sourceware.org/bugzilla/show_bug.cgi?id=6778 Signed-off-by: Michael Kerrisk <mtk.manpages@gmail.com> diff --git a/man3/expm1.3 b/man3/expm1.3 index a1fe0f7b2..460068a6d 100644 --- a/man3/expm1.3 +++ b/man3/expm1.3 @@ -144,13 +144,14 @@ T} Thread safety MT-Safe C99, POSIX.1-2001, POSIX.1-2008. .\" BSD. .SH BUGS -For some large negative +Before glibc 2.17, +.\" http://sources.redhat.com/bugzilla/show_bug.cgi?id=6778 +on certain architectures (e.g., x86, but not x86_64) +.BR expm1 () +raised a bogus underflow floating-point exception +for some large negative .I x values (where the function result approaches \-1), -.BR expm1 () -raises a bogus underflow floating-point exception. -.\" FIXME . -.\" Bug raised: http://sources.redhat.com/bugzilla/show_bug.cgi?id=6778 .PP For some large positive .I x