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.
8 Floating-point sine and cosine.
11 // The original C code, the long comment, and the constants
12 // below were from http://netlib.sandia.gov/cephes/cmath/sin.c,
13 // available from http://www.netlib.org/cephes/cmath.tgz.
14 // The go code is a simplified version of the original C.
22 // double x, y, sin();
27 // Range reduction is into intervals of pi/4. The reduction error is nearly
28 // eliminated by contriving an extended precision modular arithmetic.
30 // Two polynomial approximating functions are employed.
31 // Between 0 and pi/4 the sine is approximated by
33 // Between pi/4 and pi/2 the cosine is represented as
39 // arithmetic domain # trials peak rms
40 // DEC 0, 10 150000 3.0e-17 7.8e-18
41 // IEEE -1.07e9,+1.07e9 130000 2.1e-16 5.4e-17
43 // Partial loss of accuracy begins to occur at x = 2**30 = 1.074e9. The loss
44 // is not gradual, but jumps suddenly to about 1 part in 10e7. Results may
45 // be meaningless for x > 2**49 = 5.6e14.
53 // double x, y, cos();
58 // Range reduction is into intervals of pi/4. The reduction error is nearly
59 // eliminated by contriving an extended precision modular arithmetic.
61 // Two polynomial approximating functions are employed.
62 // Between 0 and pi/4 the cosine is approximated by
64 // Between pi/4 and pi/2 the sine is represented as
70 // arithmetic domain # trials peak rms
71 // IEEE -1.07e9,+1.07e9 130000 2.1e-16 5.4e-17
72 // DEC 0,+1.07e9 17000 3.0e-17 7.2e-18
74 // Cephes Math Library Release 2.8: June, 2000
75 // Copyright 1984, 1987, 1989, 1992, 2000 by Stephen L. Moshier
77 // The readme file at http://netlib.sandia.gov/cephes/ says:
78 // Some software in this archive may be from the book _Methods and
79 // Programs for Mathematical Functions_ (Prentice-Hall or Simon & Schuster
80 // International, 1989) or from the Cephes Mathematical Library, a
81 // commercial product. In either event, it is copyrighted by the author.
82 // What you see here may be used freely but it comes with no support or
85 // The two known misprints in the book are repaired here in the
86 // source listings for the gamma function and the incomplete beta
90 // moshier@na-net.ornl.gov
93 var _sin
= [...]float64{
94 1.58962301576546568060E-10, // 0x3de5d8fd1fd19ccd
95 -2.50507477628578072866E-8, // 0xbe5ae5e5a9291f5d
96 2.75573136213857245213E-6, // 0x3ec71de3567d48a1
97 -1.98412698295895385996E-4, // 0xbf2a01a019bfdf03
98 8.33333333332211858878E-3, // 0x3f8111111110f7d0
99 -1.66666666666666307295E-1, // 0xbfc5555555555548
103 var _cos
= [...]float64{
104 -1.13585365213876817300E-11, // 0xbda8fa49a0861a9b
105 2.08757008419747316778E-9, // 0x3e21ee9d7b4e3f05
106 -2.75573141792967388112E-7, // 0xbe927e4f7eac4bc6
107 2.48015872888517045348E-5, // 0x3efa01a019c844f5
108 -1.38888888888730564116E-3, // 0xbf56c16c16c14f91
109 4.16666666666665929218E-2, // 0x3fa555555555554b
112 // Cos returns the cosine of the radian argument x.
114 // Special cases are:
119 func libc_cos(float64) float64
121 func Cos(x
float64) float64 {
125 func cos(x
float64) float64 {
127 PI4A
= 7.85398125648498535156E-1 // 0x3fe921fb40000000, Pi/4 split into three parts
128 PI4B
= 3.77489470793079817668E-8 // 0x3e64442d00000000,
129 PI4C
= 2.69515142907905952645E-15 // 0x3ce8469898cc5170,
130 M4PI
= 1.273239544735162542821171882678754627704620361328125 // 4/pi
134 case IsNaN(x
) ||
IsInf(x
, 0):
138 // make argument positive
144 j
:= int64(x
* M4PI
) // integer part of x/(Pi/4), as integer for tests on the phase angle
145 y
:= float64(j
) // integer part of x/(Pi/4), as float
147 // map zeros to origin
152 j
&= 7 // octant modulo 2Pi radians (360 degrees)
161 z
:= ((x
- y
*PI4A
) - y
*PI4B
) - y
*PI4C
// Extended precision modular arithmetic
163 if j
== 1 || j
== 2 {
164 y
= z
+ z
*zz
*((((((_sin
[0]*zz
)+_sin
[1])*zz
+_sin
[2])*zz
+_sin
[3])*zz
+_sin
[4])*zz
+_sin
[5])
166 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])
174 // Sin returns the sine of the radian argument x.
176 // Special cases are:
182 func libc_sin(float64) float64
184 func Sin(x
float64) float64 {
188 func sin(x
float64) float64 {
190 PI4A
= 7.85398125648498535156E-1 // 0x3fe921fb40000000, Pi/4 split into three parts
191 PI4B
= 3.77489470793079817668E-8 // 0x3e64442d00000000,
192 PI4C
= 2.69515142907905952645E-15 // 0x3ce8469898cc5170,
193 M4PI
= 1.273239544735162542821171882678754627704620361328125 // 4/pi
197 case x
== 0 ||
IsNaN(x
):
198 return x
// return ±0 || NaN()
203 // make argument positive but save the sign
210 j
:= int64(x
* M4PI
) // integer part of x/(Pi/4), as integer for tests on the phase angle
211 y
:= float64(j
) // integer part of x/(Pi/4), as float
213 // map zeros to origin
218 j
&= 7 // octant modulo 2Pi radians (360 degrees)
225 z
:= ((x
- y
*PI4A
) - y
*PI4B
) - y
*PI4C
// Extended precision modular arithmetic
227 if j
== 1 || j
== 2 {
228 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])
230 y
= z
+ z
*zz
*((((((_sin
[0]*zz
)+_sin
[1])*zz
+_sin
[2])*zz
+_sin
[3])*zz
+_sin
[4])*zz
+_sin
[5])