e_acoshl.c revision 176451
1219820Sjeff 2219820Sjeff/* @(#)e_acosh.c 1.3 95/01/18 */ 3219820Sjeff/* 4219820Sjeff * ==================================================== 5219820Sjeff * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. 6219820Sjeff * 7219820Sjeff * Developed at SunSoft, a Sun Microsystems, Inc. business. 8219820Sjeff * Permission to use, copy, modify, and distribute this 9219820Sjeff * software is freely granted, provided that this notice 10219820Sjeff * is preserved. 11219820Sjeff * ==================================================== 12219820Sjeff * 13219820Sjeff */ 14219820Sjeff 15219820Sjeff#include <sys/cdefs.h> 16219820Sjeff__FBSDID("$FreeBSD: head/lib/msun/src/e_acosh.c 176451 2008-02-22 02:30:36Z das $"); 17219820Sjeff 18219820Sjeff/* __ieee754_acosh(x) 19219820Sjeff * Method : 20219820Sjeff * Based on 21219820Sjeff * acosh(x) = log [ x + sqrt(x*x-1) ] 22219820Sjeff * we have 23219820Sjeff * acosh(x) := log(x)+ln2, if x is large; else 24219820Sjeff * acosh(x) := log(2x-1/(sqrt(x*x-1)+x)) if x>2; else 25219820Sjeff * acosh(x) := log1p(t+sqrt(2.0*t+t*t)); where t=x-1. 26219820Sjeff * 27219820Sjeff * Special cases: 28219820Sjeff * acosh(x) is NaN with signal if x<1. 29219820Sjeff * acosh(NaN) is NaN without signal. 30219820Sjeff */ 31219820Sjeff 32219820Sjeff#include "math.h" 33219820Sjeff#include "math_private.h" 34219820Sjeff 35219820Sjeffstatic const double 36219820Sjeffone = 1.0, 37219820Sjeffln2 = 6.93147180559945286227e-01; /* 0x3FE62E42, 0xFEFA39EF */ 38219820Sjeff 39219820Sjeffdouble 40219820Sjeff__ieee754_acosh(double x) 41219820Sjeff{ 42219820Sjeff double t; 43219820Sjeff int32_t hx; 44219820Sjeff u_int32_t lx; 45219820Sjeff EXTRACT_WORDS(hx,lx,x); 46219820Sjeff if(hx<0x3ff00000) { /* x < 1 */ 47219820Sjeff return (x-x)/(x-x); 48219820Sjeff } else if(hx >=0x41b00000) { /* x > 2**28 */ 49219820Sjeff if(hx >=0x7ff00000) { /* x is inf of NaN */ 50219820Sjeff return x+x; 51219820Sjeff } else 52219820Sjeff return __ieee754_log(x)+ln2; /* acosh(huge)=log(2x) */ 53219820Sjeff } else if(((hx-0x3ff00000)|lx)==0) { 54219820Sjeff return 0.0; /* acosh(1) = 0 */ 55219820Sjeff } else if (hx > 0x40000000) { /* 2**28 > x > 2 */ 56219820Sjeff t=x*x; 57219820Sjeff return __ieee754_log(2.0*x-one/(x+sqrt(t-one))); 58219820Sjeff } else { /* 1<x<2 */ 59219820Sjeff t = x-one; 60219820Sjeff return log1p(t+sqrt(2.0*t+t*t)); 61219820Sjeff } 62219820Sjeff} 63219820Sjeff