gitee.com/quant1x/num@v0.3.2/math32/acosh.go (about)

     1  package math32
     2  
     3  // The original C code, the long comment, and the constants
     4  // below are from FreeBSD's /usr/src/lib/msun/src/e_acosh.c
     5  // and came with this notice. The go code is a simplified
     6  // version of the original C.
     7  //
     8  // ====================================================
     9  // Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
    10  //
    11  // Developed at SunPro, a Sun Microsystems, Inc. business.
    12  // Permission to use, copy, modify, and distribute this
    13  // software is freely granted, provided that this notice
    14  // is preserved.
    15  // ====================================================
    16  //
    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  // Acosh returns the inverse hyperbolic cosine of x.
    33  //
    34  // Special cases are:
    35  //
    36  //	Acosh(+Inf) = +Inf
    37  //	Acosh(x) = NaN if x < 1
    38  //	Acosh(NaN) = NaN
    39  func Acosh(x float32) float32 {
    40  	const Large = 1 << 28 // 2**28
    41  	// first case is special case
    42  	switch {
    43  	case x < 1 || IsNaN(x):
    44  		return NaN()
    45  	case x == 1:
    46  		return 0
    47  	case x >= Large:
    48  		return Log(x) + Ln2 // x > 2**28
    49  	case x > 2:
    50  		return Log(2*x - 1/(x+Sqrt(x*x-1))) // 2**28 > x > 2
    51  	}
    52  	t := x - 1
    53  	return Log1p(t + Sqrt(2*t+t*t)) // 2 >= x > 1
    54  }