mirror of
https://sourceware.org/git/glibc.git
synced 2024-12-26 20:51:11 +00:00
8020a80887
Similar to various other bugs in this area, some atanh implementations do not raise the underflow exception for subnormal arguments, when the result is tiny and inexact. This patch forces the exception in a similar way to previous fixes. (No change in this regard is needed for the i386 implementation; special handling to force underflows in these cases will only be needed there when the spurious underflows, bug 18049, get fixed.) Tested for x86_64, x86, powerpc and mips64. [BZ #16352] * sysdeps/i386/fpu/e_atanh.S (dbl_min): New object. (__ieee754_atanh): Force underflow exception for results with small absolute value. * sysdeps/i386/fpu/e_atanhf.S (flt_min): New object. (__ieee754_atanhf): Force underflow exception for results with small absolute value. * sysdeps/ieee754/dbl-64/e_atanh.c: Include <float.h>. (__ieee754_atanh): Force underflow exception for results with small absolute value. * sysdeps/ieee754/flt-32/e_atanhf.c: Include <float.h>. (__ieee754_atanhf): Force underflow exception for results with small absolute value. * sysdeps/ieee754/ldbl-128/e_atanhl.c: Include <float.h>. (__ieee754_atanhl): Force underflow exception for results with small absolute value. * sysdeps/ieee754/ldbl-128ibm/e_atanhl.c: Include <float.h>. (__ieee754_atanhl): Force underflow exception for results with small absolute value. * sysdeps/ieee754/ldbl-96/e_atanhl.c: Include <float.h>. (__ieee754_atanhl): Force underflow exception for results with small absolute value. * math/auto-libm-test-in: Do not allow missing underflow exceptions from atanh. * math/auto-libm-test-out: Regenerated.
79 lines
2.0 KiB
C
79 lines
2.0 KiB
C
/* s_atanhl.c -- long double version of s_atan.c.
|
|
* Conversion to long double by Ulrich Drepper,
|
|
* Cygnus Support, drepper@cygnus.com.
|
|
*/
|
|
|
|
/*
|
|
* ====================================================
|
|
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
|
*
|
|
* Developed at SunPro, a Sun Microsystems, Inc. business.
|
|
* Permission to use, copy, modify, and distribute this
|
|
* software is freely granted, provided that this notice
|
|
* is preserved.
|
|
* ====================================================
|
|
*/
|
|
|
|
/* __ieee754_atanhl(x)
|
|
* Method :
|
|
* 1.Reduced x to positive by atanh(-x) = -atanh(x)
|
|
* 2.For x>=0.5
|
|
* 1 2x x
|
|
* atanhl(x) = --- * log(1 + -------) = 0.5 * log1p(2 * --------)
|
|
* 2 1 - x 1 - x
|
|
*
|
|
* For x<0.5
|
|
* atanhl(x) = 0.5*log1pl(2x+2x*x/(1-x))
|
|
*
|
|
* Special cases:
|
|
* atanhl(x) is NaN if |x| > 1 with signal;
|
|
* atanhl(NaN) is that NaN with no signal;
|
|
* atanhl(+-1) is +-INF with signal.
|
|
*
|
|
*/
|
|
|
|
#include <float.h>
|
|
#include <math.h>
|
|
#include <math_private.h>
|
|
|
|
static const long double one = 1.0L, huge = 1e4900L;
|
|
|
|
static const long double zero = 0.0L;
|
|
|
|
long double
|
|
__ieee754_atanhl(long double x)
|
|
{
|
|
long double t;
|
|
u_int32_t jx, ix;
|
|
ieee854_long_double_shape_type u;
|
|
|
|
u.value = x;
|
|
jx = u.parts32.w0;
|
|
ix = jx & 0x7fffffff;
|
|
u.parts32.w0 = ix;
|
|
if (ix >= 0x3fff0000) /* |x| >= 1.0 or infinity or NaN */
|
|
{
|
|
if (u.value == one)
|
|
return x/zero;
|
|
else
|
|
return (x-x)/(x-x);
|
|
}
|
|
if(ix<0x3fc60000 && (huge+x)>zero) /* x < 2^-57 */
|
|
{
|
|
if (fabsl (x) < LDBL_MIN)
|
|
{
|
|
long double force_underflow = x * x;
|
|
math_force_eval (force_underflow);
|
|
}
|
|
return x;
|
|
}
|
|
|
|
if(ix<0x3ffe0000) { /* x < 0.5 */
|
|
t = u.value+u.value;
|
|
t = 0.5*__log1pl(t+t*u.value/(one-u.value));
|
|
} else
|
|
t = 0.5*__log1pl((u.value+u.value)/(one-u.value));
|
|
if(jx & 0x80000000) return -t; else return t;
|
|
}
|
|
strong_alias (__ieee754_atanhl, __atanhl_finite)
|