13a8617a8SJordan K. Hubbard /* @(#)e_atanh.c 5.1 93/09/24 */ 23a8617a8SJordan K. Hubbard /* 33a8617a8SJordan K. Hubbard * ==================================================== 43a8617a8SJordan K. Hubbard * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. 53a8617a8SJordan K. Hubbard * 63a8617a8SJordan K. Hubbard * Developed at SunPro, a Sun Microsystems, Inc. business. 73a8617a8SJordan K. Hubbard * Permission to use, copy, modify, and distribute this 83a8617a8SJordan K. Hubbard * software is freely granted, provided that this notice 93a8617a8SJordan K. Hubbard * is preserved. 103a8617a8SJordan K. Hubbard * ==================================================== 113a8617a8SJordan K. Hubbard */ 123a8617a8SJordan K. Hubbard 133a8617a8SJordan K. Hubbard #ifndef lint 147f3dea24SPeter Wemm static char rcsid[] = "$FreeBSD$"; 153a8617a8SJordan K. Hubbard #endif 163a8617a8SJordan K. Hubbard 173a8617a8SJordan K. Hubbard /* __ieee754_atanh(x) 183a8617a8SJordan K. Hubbard * Method : 193a8617a8SJordan K. Hubbard * 1.Reduced x to positive by atanh(-x) = -atanh(x) 203a8617a8SJordan K. Hubbard * 2.For x>=0.5 213a8617a8SJordan K. Hubbard * 1 2x x 223a8617a8SJordan K. Hubbard * atanh(x) = --- * log(1 + -------) = 0.5 * log1p(2 * --------) 233a8617a8SJordan K. Hubbard * 2 1 - x 1 - x 243a8617a8SJordan K. Hubbard * 253a8617a8SJordan K. Hubbard * For x<0.5 263a8617a8SJordan K. Hubbard * atanh(x) = 0.5*log1p(2x+2x*x/(1-x)) 273a8617a8SJordan K. Hubbard * 283a8617a8SJordan K. Hubbard * Special cases: 293a8617a8SJordan K. Hubbard * atanh(x) is NaN if |x| > 1 with signal; 303a8617a8SJordan K. Hubbard * atanh(NaN) is that NaN with no signal; 313a8617a8SJordan K. Hubbard * atanh(+-1) is +-INF with signal. 323a8617a8SJordan K. Hubbard * 333a8617a8SJordan K. Hubbard */ 343a8617a8SJordan K. Hubbard 353a8617a8SJordan K. Hubbard #include "math.h" 363a8617a8SJordan K. Hubbard #include "math_private.h" 373a8617a8SJordan K. Hubbard 383a8617a8SJordan K. Hubbard static const double one = 1.0, huge = 1e300; 393a8617a8SJordan K. Hubbard static const double zero = 0.0; 403a8617a8SJordan K. Hubbard 41a82bbc73SAlfred Perlstein double 42a82bbc73SAlfred Perlstein __ieee754_atanh(double x) 433a8617a8SJordan K. Hubbard { 443a8617a8SJordan K. Hubbard double t; 453a8617a8SJordan K. Hubbard int32_t hx,ix; 463a8617a8SJordan K. Hubbard u_int32_t lx; 473a8617a8SJordan K. Hubbard EXTRACT_WORDS(hx,lx,x); 483a8617a8SJordan K. Hubbard ix = hx&0x7fffffff; 493a8617a8SJordan K. Hubbard if ((ix|((lx|(-lx))>>31))>0x3ff00000) /* |x|>1 */ 503a8617a8SJordan K. Hubbard return (x-x)/(x-x); 513a8617a8SJordan K. Hubbard if(ix==0x3ff00000) 523a8617a8SJordan K. Hubbard return x/zero; 533a8617a8SJordan K. Hubbard if(ix<0x3e300000&&(huge+x)>zero) return x; /* x<2**-28 */ 543a8617a8SJordan K. Hubbard SET_HIGH_WORD(x,ix); 553a8617a8SJordan K. Hubbard if(ix<0x3fe00000) { /* x < 0.5 */ 563a8617a8SJordan K. Hubbard t = x+x; 573a8617a8SJordan K. Hubbard t = 0.5*log1p(t+t*x/(one-x)); 583a8617a8SJordan K. Hubbard } else 593a8617a8SJordan K. Hubbard t = 0.5*log1p((x+x)/(one-x)); 603a8617a8SJordan K. Hubbard if(hx>=0) return t; else return -t; 613a8617a8SJordan K. Hubbard } 62