initial cmath code and minor libm.h update
[libm] / src / math / acoshf.c
1 /* origin: FreeBSD /usr/src/lib/msun/src/e_acoshf.c */
2 /*
3  * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
4  */
5 /*
6  * ====================================================
7  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
8  *
9  * Developed at SunPro, a Sun Microsystems, Inc. business.
10  * Permission to use, copy, modify, and distribute this
11  * software is freely granted, provided that this notice
12  * is preserved.
13  * ====================================================
14  */
15
16 #include "libm.h"
17
18 static const float
19 one = 1.0,
20 ln2 = 6.9314718246e-01; /* 0x3f317218 */
21
22 float acoshf(float x)
23 {
24         float t;
25         int32_t hx;
26
27         GET_FLOAT_WORD(hx, x);
28         if (hx < 0x3f800000) {  /* x < 1 */
29                 return (x-x)/(x-x);
30         } else if (hx >= 0x4d800000) {  /* x > 2**28 */
31                 if (hx >= 0x7f800000)  /* x is inf of NaN */
32                         return x + x;
33                 return logf(x) + ln2;  /* acosh(huge)=log(2x) */
34         } else if (hx == 0x3f800000) {
35                 return 0.0;  /* acosh(1) = 0 */
36         } else if (hx > 0x40000000) {  /* 2**28 > x > 2 */
37                 t = x*x;
38                 return logf((float)2.0*x - one/(x+sqrtf(t-one)));
39         } else {                /* 1 < x < 2 */
40                 t = x-one;
41                 return log1pf(t + sqrtf((float)2.0*t+t*t));
42         }
43 }