* tree-ssa-reassoc.c (reassociate_bb): Clarify code slighly.
[official-gcc.git] / libgo / go / math / sin.go
blob75579ab4edf8c27cc8e5f733a630ba821f51cd36
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.
5 package math
7 /*
8 Floating-point sine and cosine.
9 */
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.
16 // sin.c
18 // Circular sine
20 // SYNOPSIS:
22 // double x, y, sin();
23 // y = sin( x );
25 // DESCRIPTION:
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
32 // x + x**3 P(x**2).
33 // Between pi/4 and pi/2 the cosine is represented as
34 // 1 - x**2 Q(x**2).
36 // ACCURACY:
38 // Relative error:
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.
47 // cos.c
49 // Circular cosine
51 // SYNOPSIS:
53 // double x, y, cos();
54 // y = cos( x );
56 // DESCRIPTION:
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
63 // 1 - x**2 Q(x**2).
64 // Between pi/4 and pi/2 the sine is represented as
65 // x + x**3 P(x**2).
67 // ACCURACY:
69 // Relative error:
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
83 // guarantee.
85 // The two known misprints in the book are repaired here in the
86 // source listings for the gamma function and the incomplete beta
87 // integral.
89 // Stephen L. Moshier
90 // moshier@na-net.ornl.gov
92 // sin coefficients
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
102 // cos coefficients
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:
115 // Cos(±Inf) = NaN
116 // Cos(NaN) = NaN
118 //extern cos
119 func libc_cos(float64) float64
121 func Cos(x float64) float64 {
122 return libc_cos(x)
125 func cos(x float64) float64 {
126 const (
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
132 // special cases
133 switch {
134 case IsNaN(x) || IsInf(x, 0):
135 return NaN()
138 // make argument positive
139 sign := false
140 if x < 0 {
141 x = -x
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
148 if j&1 == 1 {
152 j &= 7 // octant modulo 2Pi radians (360 degrees)
153 if j > 3 {
154 j -= 4
155 sign = !sign
157 if j > 1 {
158 sign = !sign
161 z := ((x - y*PI4A) - y*PI4B) - y*PI4C // Extended precision modular arithmetic
162 zz := z * z
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])
165 } else {
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])
168 if sign {
169 y = -y
171 return y
174 // Sin returns the sine of the radian argument x.
176 // Special cases are:
177 // Sin(±0) = ±0
178 // Sin(±Inf) = NaN
179 // Sin(NaN) = NaN
181 //extern sin
182 func libc_sin(float64) float64
184 func Sin(x float64) float64 {
185 return libc_sin(x)
188 func sin(x float64) float64 {
189 const (
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
195 // special cases
196 switch {
197 case x == 0 || IsNaN(x):
198 return x // return ±0 || NaN()
199 case IsInf(x, 0):
200 return NaN()
203 // make argument positive but save the sign
204 sign := false
205 if x < 0 {
206 x = -x
207 sign = true
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
214 if j&1 == 1 {
218 j &= 7 // octant modulo 2Pi radians (360 degrees)
219 // reflect in x axis
220 if j > 3 {
221 sign = !sign
222 j -= 4
225 z := ((x - y*PI4A) - y*PI4B) - y*PI4C // Extended precision modular arithmetic
226 zz := z * z
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])
229 } else {
230 y = z + z*zz*((((((_sin[0]*zz)+_sin[1])*zz+_sin[2])*zz+_sin[3])*zz+_sin[4])*zz+_sin[5])
232 if sign {
233 y = -y
235 return y