amath  1.8.5
Simple command line calculator
asinh.c
Go to the documentation of this file.
1 /*-
2  * Copyright (c) 2014-2018 Carsten Sonne Larsen <cs@innolan.net>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  *
25  * Project homepage:
26  * https://amath.innolan.net
27  *
28  * The original source code can be obtained from:
29  * http://www.netlib.org/fdlibm/s_asinh.c
30  *
31  * =================================================================
32  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
33  *
34  * Developed at SunSoft, a Sun Microsystems, Inc. business.
35  * Permission to use, copy, modify, and distribute this
36  * software is freely granted, provided that this notice
37  * is preserved.
38  * =================================================================
39  */
40 
41 /**
42  * @file asinh.c
43  * @brief Inverse hyperbolic sine function
44  */
45 
46 #include "prim.h"
47 
48 static const double
49  one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */
50  ln2 = 6.93147180559945286227e-01, /* 0x3FE62E42, 0xFEFA39EF */
51  huge = 1.00000000000000000000e+300;
52 
53 /**
54  * @brief Inverse hyperbolic sine function
55  * @details
56  * <pre>
57  * Method
58  * Based on
59  * asinh(x) = sign(x) * log [ |x| + sqrt(x*x+1) ]
60  *
61  * we have
62  * asinh(x) = x if 1+x*x=1,
63  * = sign(x)*(log(x)+ln2)) for large |x|, else
64  * = sign(x)*log(2|x|+1/(|x|+sqrt(x*x+1))) if|x|>2, else
65  * = sign(x)*log1p(|x| + x^2/(1 + sqrt(1+x^2)))
66  * </pre>
67  */
68 double asinh(double x)
69 {
70  double t, w;
71  int32_t hx, ix;
72  GET_HIGH_WORD(hx, x);
73  ix = hx & 0x7fffffff;
74  if (ix >= 0x7ff00000)
75  return x + x; /* x is inf or NaN */
76  if (ix < 0x3e300000)
77  { /* |x|<2**-28 */
78  if (huge + x > one)
79  return x; /* return x inexact except 0 */
80  }
81  if (ix > 0x41b00000)
82  { /* |x| > 2**28 */
83  w = log(fabs(x)) + ln2;
84  }
85  else if (ix > 0x40000000)
86  { /* 2**28 > |x| > 2.0 */
87  t = fabs(x);
88  w = log(2.0 * t + one / (sqrt(x * x + one) + t));
89  }
90  else
91  { /* 2.0 > |x| > 2**-28 */
92  t = x * x;
93  w = log1p(fabs(x) + t / (one + sqrt(one + t)));
94  }
95  if (hx > 0)
96  return w;
97  else
98  return -w;
99 }
double log(double x)
Natural logarithm function (base e)
Definition: log.c:109
double sqrt(double x)
Square root function.
Definition: sqrt.c:119
#define GET_HIGH_WORD(i, d)
Get the more significant 32 bit int from a double.
Definition: prim.h:167
double log1p(double x)
Definition: log1p.c:122
static const double ln2
Definition: asinh.c:50
static const double huge
Definition: asinh.c:51
static const double one
Definition: asinh.c:49
double fabs(double x)
Returns the absolute value of x.
Definition: fabs.c:51
double asinh(double x)
Inverse hyperbolic sine function.
Definition: asinh.c:68