Branch data 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 "cdefs-compat.h"
16 : : //__FBSDID("$FreeBSD: src/lib/msun/src/e_acosh.c,v 1.9 2008/02/22 02:30:34 das Exp $");
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 : : #include <openlibm_math.h>
34 : :
35 : : #include "math_private.h"
36 : :
37 : : static const double
38 : : one = 1.0,
39 : : ln2 = 6.93147180559945286227e-01; /* 0x3FE62E42, 0xFEFA39EF */
40 : :
41 : : OLM_DLLEXPORT double
42 : 6 : __ieee754_acosh(double x)
43 : : {
44 : : double t;
45 : : int32_t hx;
46 : : u_int32_t lx;
47 : 6 : EXTRACT_WORDS(hx,lx,x);
48 [ + + ]: 6 : if(hx<0x3ff00000) { /* x < 1 */
49 : 2 : return (x-x)/(x-x);
50 [ + + ]: 4 : } else if(hx >=0x41b00000) { /* x > 2**28 */
51 [ + - ]: 1 : if(hx >=0x7ff00000) { /* x is inf of NaN */
52 : 1 : return x+x;
53 : : } else
54 : 0 : return __ieee754_log(x)+ln2; /* acosh(huge)=log(2x) */
55 [ + + ]: 3 : } else if(((hx-0x3ff00000)|lx)==0) {
56 : 1 : return 0.0; /* acosh(1) = 0 */
57 [ + - ]: 2 : } else if (hx > 0x40000000) { /* 2**28 > x > 2 */
58 : 2 : t=x*x;
59 : 2 : return __ieee754_log(2.0*x-one/(x+sqrt(t-one)));
60 : : } else { /* 1<x<2 */
61 : 0 : t = x-one;
62 : 0 : return log1p(t+sqrt(2.0*t+t*t));
63 : : }
64 : : }
65 : :
66 : : #if (LDBL_MANT_DIG == 53)
67 : : openlibm_weak_reference(acosh, acoshl);
68 : : #endif
|