Line data Source code
1 :
2 : /* @(#)e_acosh.c 1.3 95/01/18 */
3 : /*
4 : * ====================================================
5 : * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
6 : *
7 : * Developed at SunSoft, a Sun Microsystems, Inc. business.
8 : * Permission to use, copy, modify, and distribute this
9 : * software is freely granted, provided that this notice
10 : * is preserved.
11 : * ====================================================
12 : *
13 : */
14 :
15 : //#include <sys/cdefs.h>
16 : //__FBSDID("$FreeBSD$");
17 :
18 : /* __ieee754_acosh(x)
19 : * Method :
20 : * Based on
21 : * acosh(x) = log [ x + sqrt(x*x-1) ]
22 : * we have
23 : * acosh(x) := log(x)+ln2, if x is large; else
24 : * acosh(x) := log(2x-1/(sqrt(x*x-1)+x)) if x>2; else
25 : * acosh(x) := log1p(t+sqrt(2.0*t+t*t)); where t=x-1.
26 : *
27 : * Special cases:
28 : * acosh(x) is NaN with signal if x<1.
29 : * acosh(NaN) is NaN without signal.
30 : */
31 :
32 : #include <float.h>
33 :
34 : #include "math_private.h"
35 :
36 : static const double
37 : one = 1.0,
38 : ln2 = 6.93147180559945286227e-01; /* 0x3FE62E42, 0xFEFA39EF */
39 :
40 : double
41 0 : __ieee754_acosh(double x)
42 : {
43 : double t;
44 : int32_t hx;
45 : u_int32_t lx;
46 0 : EXTRACT_WORDS(hx,lx,x);
47 0 : if(hx<0x3ff00000) { /* x < 1 */
48 0 : return (x-x)/(x-x);
49 0 : } else if(hx >=0x41b00000) { /* x > 2**28 */
50 0 : if(hx >=0x7ff00000) { /* x is inf of NaN */
51 0 : return x+x;
52 : } else
53 0 : return __ieee754_log(x)+ln2; /* acosh(huge)=log(2x) */
54 0 : } else if(((hx-0x3ff00000)|lx)==0) {
55 0 : return 0.0; /* acosh(1) = 0 */
56 0 : } else if (hx > 0x40000000) { /* 2**28 > x > 2 */
57 0 : t=x*x;
58 0 : return __ieee754_log(2.0*x-one/(x+sqrt(t-one)));
59 : } else { /* 1<x<2 */
60 0 : t = x-one;
61 0 : return log1p(t+sqrt(2.0*t+t*t));
62 : }
63 : }
|