...

Source file src/math/asinh.go

Documentation: math

		 1  // Copyright 2010 The Go Authors. All rights reserved.
		 2  // Use of this source code is governed by a BSD-style
		 3  // license that can be found in the LICENSE file.
		 4  
		 5  package math
		 6  
		 7  // The original C code, the long comment, and the constants
		 8  // below are from FreeBSD's /usr/src/lib/msun/src/s_asinh.c
		 9  // and came with this notice. The go code is a simplified
		10  // version of the original C.
		11  //
		12  // ====================================================
		13  // Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
		14  //
		15  // Developed at SunPro, a Sun Microsystems, Inc. business.
		16  // Permission to use, copy, modify, and distribute this
		17  // software is freely granted, provided that this notice
		18  // is preserved.
		19  // ====================================================
		20  //
		21  //
		22  // asinh(x)
		23  // Method :
		24  //	Based on
		25  //					asinh(x) = sign(x) * log [ |x| + sqrt(x*x+1) ]
		26  //	we have
		27  //	asinh(x) := x	if	1+x*x=1,
		28  //					 := sign(x)*(log(x)+ln2)) for large |x|, else
		29  //					 := sign(x)*log(2|x|+1/(|x|+sqrt(x*x+1))) if|x|>2, else
		30  //					 := sign(x)*log1p(|x| + x**2/(1 + sqrt(1+x**2)))
		31  //
		32  
		33  // Asinh returns the inverse hyperbolic sine of x.
		34  //
		35  // Special cases are:
		36  //	Asinh(±0) = ±0
		37  //	Asinh(±Inf) = ±Inf
		38  //	Asinh(NaN) = NaN
		39  func Asinh(x float64) float64 {
		40  	if haveArchAsinh {
		41  		return archAsinh(x)
		42  	}
		43  	return asinh(x)
		44  }
		45  
		46  func asinh(x float64) float64 {
		47  	const (
		48  		Ln2			= 6.93147180559945286227e-01 // 0x3FE62E42FEFA39EF
		49  		NearZero = 1.0 / (1 << 28)						// 2**-28
		50  		Large		= 1 << 28										// 2**28
		51  	)
		52  	// special cases
		53  	if IsNaN(x) || IsInf(x, 0) {
		54  		return x
		55  	}
		56  	sign := false
		57  	if x < 0 {
		58  		x = -x
		59  		sign = true
		60  	}
		61  	var temp float64
		62  	switch {
		63  	case x > Large:
		64  		temp = Log(x) + Ln2 // |x| > 2**28
		65  	case x > 2:
		66  		temp = Log(2*x + 1/(Sqrt(x*x+1)+x)) // 2**28 > |x| > 2.0
		67  	case x < NearZero:
		68  		temp = x // |x| < 2**-28
		69  	default:
		70  		temp = Log1p(x + x*x/(1+Sqrt(1+x*x))) // 2.0 > |x| > 2**-28
		71  	}
		72  	if sign {
		73  		temp = -temp
		74  	}
		75  	return temp
		76  }
		77  

View as plain text