PageRenderTime 40ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/third_party/gofrontend/libgo/go/math/sin.go

http://github.com/axw/llgo
Go | 236 lines | 107 code | 21 blank | 108 comment | 26 complexity | c9f89142e0849fc93765e327bad8e0ab MD5 | raw file
Possible License(s): BSD-3-Clause, MIT
  1. // Copyright 2011 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. package math
  5. /*
  6. Floating-point sine and cosine.
  7. */
  8. // The original C code, the long comment, and the constants
  9. // below were from http://netlib.sandia.gov/cephes/cmath/sin.c,
  10. // available from http://www.netlib.org/cephes/cmath.tgz.
  11. // The go code is a simplified version of the original C.
  12. //
  13. // sin.c
  14. //
  15. // Circular sine
  16. //
  17. // SYNOPSIS:
  18. //
  19. // double x, y, sin();
  20. // y = sin( x );
  21. //
  22. // DESCRIPTION:
  23. //
  24. // Range reduction is into intervals of pi/4. The reduction error is nearly
  25. // eliminated by contriving an extended precision modular arithmetic.
  26. //
  27. // Two polynomial approximating functions are employed.
  28. // Between 0 and pi/4 the sine is approximated by
  29. // x + x**3 P(x**2).
  30. // Between pi/4 and pi/2 the cosine is represented as
  31. // 1 - x**2 Q(x**2).
  32. //
  33. // ACCURACY:
  34. //
  35. // Relative error:
  36. // arithmetic domain # trials peak rms
  37. // DEC 0, 10 150000 3.0e-17 7.8e-18
  38. // IEEE -1.07e9,+1.07e9 130000 2.1e-16 5.4e-17
  39. //
  40. // Partial loss of accuracy begins to occur at x = 2**30 = 1.074e9. The loss
  41. // is not gradual, but jumps suddenly to about 1 part in 10e7. Results may
  42. // be meaningless for x > 2**49 = 5.6e14.
  43. //
  44. // cos.c
  45. //
  46. // Circular cosine
  47. //
  48. // SYNOPSIS:
  49. //
  50. // double x, y, cos();
  51. // y = cos( x );
  52. //
  53. // DESCRIPTION:
  54. //
  55. // Range reduction is into intervals of pi/4. The reduction error is nearly
  56. // eliminated by contriving an extended precision modular arithmetic.
  57. //
  58. // Two polynomial approximating functions are employed.
  59. // Between 0 and pi/4 the cosine is approximated by
  60. // 1 - x**2 Q(x**2).
  61. // Between pi/4 and pi/2 the sine is represented as
  62. // x + x**3 P(x**2).
  63. //
  64. // ACCURACY:
  65. //
  66. // Relative error:
  67. // arithmetic domain # trials peak rms
  68. // IEEE -1.07e9,+1.07e9 130000 2.1e-16 5.4e-17
  69. // DEC 0,+1.07e9 17000 3.0e-17 7.2e-18
  70. //
  71. // Cephes Math Library Release 2.8: June, 2000
  72. // Copyright 1984, 1987, 1989, 1992, 2000 by Stephen L. Moshier
  73. //
  74. // The readme file at http://netlib.sandia.gov/cephes/ says:
  75. // Some software in this archive may be from the book _Methods and
  76. // Programs for Mathematical Functions_ (Prentice-Hall or Simon & Schuster
  77. // International, 1989) or from the Cephes Mathematical Library, a
  78. // commercial product. In either event, it is copyrighted by the author.
  79. // What you see here may be used freely but it comes with no support or
  80. // guarantee.
  81. //
  82. // The two known misprints in the book are repaired here in the
  83. // source listings for the gamma function and the incomplete beta
  84. // integral.
  85. //
  86. // Stephen L. Moshier
  87. // moshier@na-net.ornl.gov
  88. // sin coefficients
  89. var _sin = [...]float64{
  90. 1.58962301576546568060E-10, // 0x3de5d8fd1fd19ccd
  91. -2.50507477628578072866E-8, // 0xbe5ae5e5a9291f5d
  92. 2.75573136213857245213E-6, // 0x3ec71de3567d48a1
  93. -1.98412698295895385996E-4, // 0xbf2a01a019bfdf03
  94. 8.33333333332211858878E-3, // 0x3f8111111110f7d0
  95. -1.66666666666666307295E-1, // 0xbfc5555555555548
  96. }
  97. // cos coefficients
  98. var _cos = [...]float64{
  99. -1.13585365213876817300E-11, // 0xbda8fa49a0861a9b
  100. 2.08757008419747316778E-9, // 0x3e21ee9d7b4e3f05
  101. -2.75573141792967388112E-7, // 0xbe927e4f7eac4bc6
  102. 2.48015872888517045348E-5, // 0x3efa01a019c844f5
  103. -1.38888888888730564116E-3, // 0xbf56c16c16c14f91
  104. 4.16666666666665929218E-2, // 0x3fa555555555554b
  105. }
  106. // Cos returns the cosine of the radian argument x.
  107. //
  108. // Special cases are:
  109. // Cos(±Inf) = NaN
  110. // Cos(NaN) = NaN
  111. //extern cos
  112. func libc_cos(float64) float64
  113. func Cos(x float64) float64 {
  114. return libc_cos(x)
  115. }
  116. func cos(x float64) float64 {
  117. const (
  118. PI4A = 7.85398125648498535156E-1 // 0x3fe921fb40000000, Pi/4 split into three parts
  119. PI4B = 3.77489470793079817668E-8 // 0x3e64442d00000000,
  120. PI4C = 2.69515142907905952645E-15 // 0x3ce8469898cc5170,
  121. M4PI = 1.273239544735162542821171882678754627704620361328125 // 4/pi
  122. )
  123. // special cases
  124. switch {
  125. case IsNaN(x) || IsInf(x, 0):
  126. return NaN()
  127. }
  128. // make argument positive
  129. sign := false
  130. if x < 0 {
  131. x = -x
  132. }
  133. j := int64(x * M4PI) // integer part of x/(Pi/4), as integer for tests on the phase angle
  134. y := float64(j) // integer part of x/(Pi/4), as float
  135. // map zeros to origin
  136. if j&1 == 1 {
  137. j += 1
  138. y += 1
  139. }
  140. j &= 7 // octant modulo 2Pi radians (360 degrees)
  141. if j > 3 {
  142. j -= 4
  143. sign = !sign
  144. }
  145. if j > 1 {
  146. sign = !sign
  147. }
  148. z := ((x - y*PI4A) - y*PI4B) - y*PI4C // Extended precision modular arithmetic
  149. zz := z * z
  150. if j == 1 || j == 2 {
  151. y = z + z*zz*((((((_sin[0]*zz)+_sin[1])*zz+_sin[2])*zz+_sin[3])*zz+_sin[4])*zz+_sin[5])
  152. } else {
  153. y = 1.0 - 0.5*zz + zz*zz*((((((_cos[0]*zz)+_cos[1])*zz+_cos[2])*zz+_cos[3])*zz+_cos[4])*zz+_cos[5])
  154. }
  155. if sign {
  156. y = -y
  157. }
  158. return y
  159. }
  160. // Sin returns the sine of the radian argument x.
  161. //
  162. // Special cases are:
  163. // Sin(±0) = ±0
  164. // Sin(±Inf) = NaN
  165. // Sin(NaN) = NaN
  166. //extern sin
  167. func libc_sin(float64) float64
  168. func Sin(x float64) float64 {
  169. return libc_sin(x)
  170. }
  171. func sin(x float64) float64 {
  172. const (
  173. PI4A = 7.85398125648498535156E-1 // 0x3fe921fb40000000, Pi/4 split into three parts
  174. PI4B = 3.77489470793079817668E-8 // 0x3e64442d00000000,
  175. PI4C = 2.69515142907905952645E-15 // 0x3ce8469898cc5170,
  176. M4PI = 1.273239544735162542821171882678754627704620361328125 // 4/pi
  177. )
  178. // special cases
  179. switch {
  180. case x == 0 || IsNaN(x):
  181. return x // return ±0 || NaN()
  182. case IsInf(x, 0):
  183. return NaN()
  184. }
  185. // make argument positive but save the sign
  186. sign := false
  187. if x < 0 {
  188. x = -x
  189. sign = true
  190. }
  191. j := int64(x * M4PI) // integer part of x/(Pi/4), as integer for tests on the phase angle
  192. y := float64(j) // integer part of x/(Pi/4), as float
  193. // map zeros to origin
  194. if j&1 == 1 {
  195. j += 1
  196. y += 1
  197. }
  198. j &= 7 // octant modulo 2Pi radians (360 degrees)
  199. // reflect in x axis
  200. if j > 3 {
  201. sign = !sign
  202. j -= 4
  203. }
  204. z := ((x - y*PI4A) - y*PI4B) - y*PI4C // Extended precision modular arithmetic
  205. zz := z * z
  206. if j == 1 || j == 2 {
  207. y = 1.0 - 0.5*zz + zz*zz*((((((_cos[0]*zz)+_cos[1])*zz+_cos[2])*zz+_cos[3])*zz+_cos[4])*zz+_cos[5])
  208. } else {
  209. y = z + z*zz*((((((_sin[0]*zz)+_sin[1])*zz+_sin[2])*zz+_sin[3])*zz+_sin[4])*zz+_sin[5])
  210. }
  211. if sign {
  212. y = -y
  213. }
  214. return y
  215. }