gitee.com/quant1x/num@v0.3.2/math32/atanh.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_atanh.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_atanh(x) 19 // Method : 20 // 1. Reduce x to positive by atanh(-x) = -atanh(x) 21 // 2. For x>=0.5 22 // 1 2x x 23 // atanh(x) = --- * log(1 + -------) = 0.5 * log1p(2 * --------) 24 // 2 1 - x 1 - x 25 // 26 // For x<0.5 27 // atanh(x) = 0.5*log1p(2x+2x*x/(1-x)) 28 // 29 // Special cases: 30 // atanh(x) is NaN if |x| > 1 with signal; 31 // atanh(NaN) is that NaN with no signal; 32 // atanh(+-1) is +-INF with signal. 33 // 34 35 // Atanh returns the inverse hyperbolic tangent of x. 36 // 37 // Special cases are: 38 // 39 // Atanh(1) = +Inf 40 // Atanh(±0) = ±0 41 // Atanh(-1) = -Inf 42 // Atanh(x) = NaN if x < -1 or x > 1 43 // Atanh(NaN) = NaN 44 func Atanh(x float32) float32 { 45 const NearZero = 1.0 / (1 << 28) // 2**-28 46 // special cases 47 switch { 48 case x < -1 || x > 1 || IsNaN(x): 49 return NaN() 50 case x == 1: 51 return Inf(1) 52 case x == -1: 53 return Inf(-1) 54 } 55 sign := false 56 if x < 0 { 57 x = -x 58 sign = true 59 } 60 var temp float32 61 switch { 62 case x < NearZero: 63 temp = x 64 case x < 0.5: 65 temp = x + x 66 temp = 0.5 * Log1p(temp+temp*x/(1-x)) 67 default: 68 temp = 0.5 * Log1p((x+x)/(1-x)) 69 } 70 if sign { 71 temp = -temp 72 } 73 return temp 74 }