11dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
21dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* @(#)e_atanh.c 1.3 95/01/18 */
31dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*
41dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ====================================================
51dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
61dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
71dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Developed at SunSoft, a Sun Microsystems, Inc. business.
81dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Permission to use, copy, modify, and distribute this
91dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * software is freely granted, provided that this notice
101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * is preserved.
111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ====================================================
121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */
141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
15a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#include <sys/cdefs.h>
16a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes__FBSDID("$FreeBSD$");
171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* __ieee754_atanh(x)
191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Method :
201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *    1.Reduced x to positive by atanh(-x) = -atanh(x)
211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *    2.For x>=0.5
221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *                  1              2x                          x
231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *	atanh(x) = --- * log(1 + -------) = 0.5 * log1p(2 * --------)
241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *                  2             1 - x                      1 - x
251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 	For x<0.5
271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *	atanh(x) = 0.5*log1p(2x+2x*x/(1-x))
281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Special cases:
301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *	atanh(x) is NaN if |x| > 1 with signal;
311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *	atanh(NaN) is that NaN with no signal;
321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *	atanh(+-1) is +-INF with signal.
331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */
351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
3678419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#include <float.h>
3778419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes
381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "math.h"
391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "math_private.h"
401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic const double one = 1.0, huge = 1e300;
421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic const double zero = 0.0;
431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectdouble
451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project__ieee754_atanh(double x)
461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	double t;
481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int32_t hx,ix;
491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	u_int32_t lx;
501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	EXTRACT_WORDS(hx,lx,x);
511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	ix = hx&0x7fffffff;
521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if ((ix|((lx|(-lx))>>31))>0x3ff00000) /* |x|>1 */
531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	    return (x-x)/(x-x);
541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if(ix==0x3ff00000)
551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	    return x/zero;
561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if(ix<0x3e300000&&(huge+x)>zero) return x;	/* x<2**-28 */
571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	SET_HIGH_WORD(x,ix);
581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if(ix<0x3fe00000) {		/* x < 0.5 */
591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	    t = x+x;
601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	    t = 0.5*log1p(t+t*x/(one-x));
611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	} else
621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	    t = 0.5*log1p((x+x)/(one-x));
631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if(hx>=0) return t; else return -t;
641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
6578419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes
6678419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#if LDBL_MANT_DIG == 53
6778419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes__weak_reference(atanh, atanhl);
6878419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#endif
69