acosh.go 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. package math32
  2. // The original C code, the long comment, and the constants
  3. // below are from FreeBSD's /usr/src/lib/msun/src/e_acosh.c
  4. // and came with this notice. The go code is a simplified
  5. // version of the original C.
  6. //
  7. // ====================================================
  8. // Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
  9. //
  10. // Developed at SunPro, a Sun Microsystems, Inc. business.
  11. // Permission to use, copy, modify, and distribute this
  12. // software is freely granted, provided that this notice
  13. // is preserved.
  14. // ====================================================
  15. //
  16. //
  17. // __ieee754_acosh(x)
  18. // Method :
  19. // Based on
  20. // acosh(x) = log [ x + sqrt(x*x-1) ]
  21. // we have
  22. // acosh(x) := log(x)+ln2, if x is large; else
  23. // acosh(x) := log(2x-1/(sqrt(x*x-1)+x)) if x>2; else
  24. // acosh(x) := log1p(t+sqrt(2.0*t+t*t)); where t=x-1.
  25. //
  26. // Special cases:
  27. // acosh(x) is NaN with signal if x<1.
  28. // acosh(NaN) is NaN without signal.
  29. //
  30. // Acosh returns the inverse hyperbolic cosine of x.
  31. //
  32. // Special cases are:
  33. // Acosh(+Inf) = +Inf
  34. // Acosh(x) = NaN if x < 1
  35. // Acosh(NaN) = NaN
  36. func Acosh(x float32) float32 {
  37. const Large = 1 << 28 // 2**28
  38. // first case is special case
  39. switch {
  40. case x < 1 || IsNaN(x):
  41. return NaN()
  42. case x == 1:
  43. return 0
  44. case x >= Large:
  45. return Log(x) + Ln2 // x > 2**28
  46. case x > 2:
  47. return Log(2*x - 1/(x+Sqrt(x*x-1))) // 2**28 > x > 2
  48. }
  49. t := x - 1
  50. return Log1p(t + Sqrt(2*t+t*t)) // 2 >= x > 1
  51. }