e_acoshl.c revision 8870
1139826Simp/* @(#)e_acosh.c 5.1 93/09/24 */
253541Sshin/*
353541Sshin * ====================================================
453541Sshin * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
553541Sshin *
653541Sshin * Developed at SunPro, a Sun Microsystems, Inc. business.
753541Sshin * Permission to use, copy, modify, and distribute this
853541Sshin * software is freely granted, provided that this notice
953541Sshin * is preserved.
1053541Sshin * ====================================================
1153541Sshin */
1253541Sshin
1353541Sshin#ifndef lint
1453541Sshinstatic char rcsid[] = "$Id: e_acosh.c,v 1.1.1.1 1994/08/19 09:39:43 jkh Exp $";
1553541Sshin#endif
1653541Sshin
1753541Sshin/* __ieee754_acosh(x)
1853541Sshin * Method :
1953541Sshin *	Based on
2053541Sshin *		acosh(x) = log [ x + sqrt(x*x-1) ]
2153541Sshin *	we have
2253541Sshin *		acosh(x) := log(x)+ln2,	if x is large; else
2353541Sshin *		acosh(x) := log(2x-1/(sqrt(x*x-1)+x)) if x>2; else
2453541Sshin *		acosh(x) := log1p(t+sqrt(2.0*t+t*t)); where t=x-1.
2553541Sshin *
2653541Sshin * Special cases:
2753541Sshin *	acosh(x) is NaN with signal if x<1.
28174510Sobrien *	acosh(NaN) is NaN without signal.
29174510Sobrien */
3053541Sshin
3153541Sshin#include "math.h"
32174510Sobrien#include "math_private.h"
33174510Sobrien
34174510Sobrien#ifdef __STDC__
3553541Sshinstatic const double
3653541Sshin#else
3753541Sshinstatic double
3853541Sshin#endif
3953541Sshinone	= 1.0,
4053541Sshinln2	= 6.93147180559945286227e-01;  /* 0x3FE62E42, 0xFEFA39EF */
4153541Sshin
4253541Sshin#ifdef __STDC__
4353541Sshin	double __ieee754_acosh(double x)
4453541Sshin#else
4553541Sshin	double __ieee754_acosh(x)
4653541Sshin	double x;
4753541Sshin#endif
4853541Sshin{
49195699Srwatson	double t;
5053541Sshin	int32_t hx;
5153541Sshin	u_int32_t lx;
5253541Sshin	EXTRACT_WORDS(hx,lx,x);
5362587Sitojun	if(hx<0x3ff00000) {		/* x < 1 */
5453541Sshin	    return (x-x)/(x-x);
5562587Sitojun	} else if(hx >=0x41b00000) {	/* x > 2**28 */
56121684Sume	    if(hx >=0x7ff00000) {	/* x is inf of NaN */
57121684Sume	        return x+x;
5853541Sshin	    } else
59184307Srwatson		return __ieee754_log(x)+ln2;	/* acosh(huge)=log(2x) */
60184307Srwatson	} else if(((hx-0x3ff00000)|lx)==0) {
6153541Sshin	    return 0.0;			/* acosh(1) = 0 */
6253541Sshin	} else if (hx > 0x40000000) {	/* 2**28 > x > 2 */
6353541Sshin	    t=x*x;
6453541Sshin	    return __ieee754_log(2.0*x-one/(x+sqrt(t-one)));
6553541Sshin	} else {			/* 1<x<2 */
6662587Sitojun	    t = x-one;
6753541Sshin	    return log1p(t+sqrt(2.0*t+t*t));
68175162Sobrien	}
69175162Sobrien}
70175162Sobrien