mirror of
https://github.com/golang/go
synced 2024-11-25 09:17:57 -07:00
math: add Cbrt and Sincos; x87 versions of Sincos, Frexp, Ldexp
Added special condition and benchmarks for Cbrt, Sincos. Took Frexp and Ldexp out of bits.go. R=rsc CC=golang-dev https://golang.org/cl/206084
This commit is contained in:
parent
4af0a58ea9
commit
c3fa32c747
@ -17,12 +17,15 @@ OFILES_386=\
|
|||||||
exp2_386.$O\
|
exp2_386.$O\
|
||||||
fabs_386.$O\
|
fabs_386.$O\
|
||||||
floor_386.$O\
|
floor_386.$O\
|
||||||
|
frexp_386.$O\
|
||||||
fmod_386.$O\
|
fmod_386.$O\
|
||||||
hypot_386.$O\
|
hypot_386.$O\
|
||||||
|
ldexp_386.$O\
|
||||||
log_386.$O\
|
log_386.$O\
|
||||||
log1p_386.$O\
|
log1p_386.$O\
|
||||||
modf_386.$O\
|
modf_386.$O\
|
||||||
sin_386.$O\
|
sin_386.$O\
|
||||||
|
sincos_386.$O\
|
||||||
sqrt_386.$O\
|
sqrt_386.$O\
|
||||||
tan_386.$O\
|
tan_386.$O\
|
||||||
|
|
||||||
@ -37,6 +40,7 @@ ALLGOFILES=\
|
|||||||
atanh.go\
|
atanh.go\
|
||||||
atan2.go\
|
atan2.go\
|
||||||
bits.go\
|
bits.go\
|
||||||
|
cbrt.go\
|
||||||
const.go\
|
const.go\
|
||||||
copysign.go\
|
copysign.go\
|
||||||
erf.go\
|
erf.go\
|
||||||
@ -46,7 +50,9 @@ ALLGOFILES=\
|
|||||||
fdim.go\
|
fdim.go\
|
||||||
floor.go\
|
floor.go\
|
||||||
fmod.go\
|
fmod.go\
|
||||||
|
frexp.go\
|
||||||
hypot.go\
|
hypot.go\
|
||||||
|
ldexp.go\
|
||||||
log.go\
|
log.go\
|
||||||
log1p.go\
|
log1p.go\
|
||||||
modf.go\
|
modf.go\
|
||||||
@ -54,6 +60,7 @@ ALLGOFILES=\
|
|||||||
pow.go\
|
pow.go\
|
||||||
pow10.go\
|
pow10.go\
|
||||||
sin.go\
|
sin.go\
|
||||||
|
sincos.go\
|
||||||
sinh.go\
|
sinh.go\
|
||||||
sqrt.go\
|
sqrt.go\
|
||||||
sqrt_port.go\
|
sqrt_port.go\
|
||||||
|
@ -112,6 +112,18 @@ var atan2 = []float64{
|
|||||||
1.3902530903455392306872261e+00,
|
1.3902530903455392306872261e+00,
|
||||||
2.2859857424479142655411058e+00,
|
2.2859857424479142655411058e+00,
|
||||||
}
|
}
|
||||||
|
var cbrt = []float64{
|
||||||
|
1.7075799841925094446722675e+00,
|
||||||
|
1.9779982212970353936691498e+00,
|
||||||
|
-6.5177429017779910853339447e-01,
|
||||||
|
-1.7111838886544019873338113e+00,
|
||||||
|
2.1279920909827937423960472e+00,
|
||||||
|
1.4303536770460741452312367e+00,
|
||||||
|
1.7357021059106154902341052e+00,
|
||||||
|
1.3972633462554328350552916e+00,
|
||||||
|
1.2221149580905388454977636e+00,
|
||||||
|
-2.0556003730500069110343596e+00,
|
||||||
|
}
|
||||||
var ceil = []float64{
|
var ceil = []float64{
|
||||||
5.0000000000000000e+00,
|
5.0000000000000000e+00,
|
||||||
8.0000000000000000e+00,
|
8.0000000000000000e+00,
|
||||||
@ -546,6 +558,17 @@ var atan2SC = []float64{
|
|||||||
NaN(),
|
NaN(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var vfcbrtSC = []float64{
|
||||||
|
Inf(-1),
|
||||||
|
Inf(1),
|
||||||
|
NaN(),
|
||||||
|
}
|
||||||
|
var cbrtSC = []float64{
|
||||||
|
Inf(-1),
|
||||||
|
Inf(1),
|
||||||
|
NaN(),
|
||||||
|
}
|
||||||
|
|
||||||
var vfceilSC = []float64{
|
var vfceilSC = []float64{
|
||||||
Inf(-1),
|
Inf(-1),
|
||||||
Inf(1),
|
Inf(1),
|
||||||
@ -993,6 +1016,19 @@ func TestAtan2(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCbrt(t *testing.T) {
|
||||||
|
for i := 0; i < len(vf); i++ {
|
||||||
|
if f := Cbrt(vf[i]); !veryclose(cbrt[i], f) {
|
||||||
|
t.Errorf("Cbrt(%g) = %g, want %g\n", vf[i], f, cbrt[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for i := 0; i < len(vfcbrtSC); i++ {
|
||||||
|
if f := Cbrt(vfcbrtSC[i]); !alike(cbrtSC[i], f) {
|
||||||
|
t.Errorf("Cbrt(%g) = %g, want %g\n", vfcbrtSC[i], f, cbrtSC[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestCeil(t *testing.T) {
|
func TestCeil(t *testing.T) {
|
||||||
for i := 0; i < len(vf); i++ {
|
for i := 0; i < len(vf); i++ {
|
||||||
if f := Ceil(vf[i]); ceil[i] != f {
|
if f := Ceil(vf[i]); ceil[i] != f {
|
||||||
@ -1309,6 +1345,14 @@ func TestSin(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSincos(t *testing.T) {
|
||||||
|
for i := 0; i < len(vf); i++ {
|
||||||
|
if s, c := Sincos(vf[i]); !close(sin[i], s) || !close(cos[i], c) {
|
||||||
|
t.Errorf("Sincos(%g) = %g, %g want %g, %g\n", vf[i], s, c, sin[i], cos[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestSinh(t *testing.T) {
|
func TestSinh(t *testing.T) {
|
||||||
for i := 0; i < len(vf); i++ {
|
for i := 0; i < len(vf); i++ {
|
||||||
if f := Sinh(vf[i]); !close(sinh[i], f) {
|
if f := Sinh(vf[i]); !close(sinh[i], f) {
|
||||||
@ -1366,6 +1410,17 @@ func TestTrunc(t *testing.T) {
|
|||||||
|
|
||||||
// Check that math functions of high angle values
|
// Check that math functions of high angle values
|
||||||
// return similar results to low angle values
|
// return similar results to low angle values
|
||||||
|
func TestLargeCos(t *testing.T) {
|
||||||
|
large := float64(100000 * Pi)
|
||||||
|
for i := 0; i < len(vf); i++ {
|
||||||
|
f1 := Cos(vf[i])
|
||||||
|
f2 := Cos(vf[i] + large)
|
||||||
|
if !kindaclose(f1, f2) {
|
||||||
|
t.Errorf("Cos(%g) = %g, want %g\n", vf[i]+large, f2, f1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestLargeSin(t *testing.T) {
|
func TestLargeSin(t *testing.T) {
|
||||||
large := float64(100000 * Pi)
|
large := float64(100000 * Pi)
|
||||||
for i := 0; i < len(vf); i++ {
|
for i := 0; i < len(vf); i++ {
|
||||||
@ -1377,13 +1432,13 @@ func TestLargeSin(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestLargeCos(t *testing.T) {
|
func TestLargeSincos(t *testing.T) {
|
||||||
large := float64(100000 * Pi)
|
large := float64(100000 * Pi)
|
||||||
for i := 0; i < len(vf); i++ {
|
for i := 0; i < len(vf); i++ {
|
||||||
f1 := Cos(vf[i])
|
f1, g1 := Sincos(vf[i])
|
||||||
f2 := Cos(vf[i] + large)
|
f2, g2 := Sincos(vf[i] + large)
|
||||||
if !kindaclose(f1, f2) {
|
if !kindaclose(f1, f2) || !kindaclose(g1, g2) {
|
||||||
t.Errorf("Cos(%g) = %g, want %g\n", vf[i]+large, f2, f1)
|
t.Errorf("Sincos(%g) = %g, %g, want %g, %g\n", vf[i]+large, f2, g2, f1, g1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1469,6 +1524,12 @@ func BenchmarkAtan2(b *testing.B) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func BenchmarkCbrt(b *testing.B) {
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
Cbrt(10)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func BenchmarkCeil(b *testing.B) {
|
func BenchmarkCeil(b *testing.B) {
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
Ceil(.5)
|
Ceil(.5)
|
||||||
@ -1625,6 +1686,12 @@ func BenchmarkSin(b *testing.B) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func BenchmarkSincos(b *testing.B) {
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
Sincos(.5)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func BenchmarkSinh(b *testing.B) {
|
func BenchmarkSinh(b *testing.B) {
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
Sinh(2.5)
|
Sinh(2.5)
|
||||||
|
@ -47,51 +47,3 @@ func IsInf(f float64, sign int) bool {
|
|||||||
// return sign >= 0 && x == uvinf || sign <= 0 && x == uvneginf;
|
// return sign >= 0 && x == uvinf || sign <= 0 && x == uvneginf;
|
||||||
return sign >= 0 && f > MaxFloat64 || sign <= 0 && f < -MaxFloat64
|
return sign >= 0 && f > MaxFloat64 || sign <= 0 && f < -MaxFloat64
|
||||||
}
|
}
|
||||||
|
|
||||||
// Frexp breaks f into a normalized fraction
|
|
||||||
// and an integral power of two.
|
|
||||||
// It returns frac and exp satisfying f == frac × 2<sup>exp</sup>,
|
|
||||||
// with the absolute value of frac in the interval [½, 1).
|
|
||||||
func Frexp(f float64) (frac float64, exp int) {
|
|
||||||
// TODO(rsc): Remove manual inlining of IsNaN, IsInf
|
|
||||||
// when compiler does it for us
|
|
||||||
// special cases
|
|
||||||
switch {
|
|
||||||
case f == 0:
|
|
||||||
return
|
|
||||||
case f < -MaxFloat64 || f > MaxFloat64 || f != f: // IsInf(f, 0) || IsNaN(f):
|
|
||||||
frac = f
|
|
||||||
return
|
|
||||||
}
|
|
||||||
x := Float64bits(f)
|
|
||||||
exp = int((x>>shift)&mask) - bias
|
|
||||||
x &^= mask << shift
|
|
||||||
x |= bias << shift
|
|
||||||
frac = Float64frombits(x)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ldexp is the inverse of Frexp.
|
|
||||||
// It returns frac × 2<sup>exp</sup>.
|
|
||||||
func Ldexp(frac float64, exp int) float64 {
|
|
||||||
// TODO(rsc): Remove manual inlining of IsNaN, IsInf
|
|
||||||
// when compiler does it for us
|
|
||||||
// special cases
|
|
||||||
if frac != frac { // IsNaN(frac)
|
|
||||||
return NaN()
|
|
||||||
}
|
|
||||||
x := Float64bits(frac)
|
|
||||||
exp += int(x>>shift) & mask
|
|
||||||
if exp <= 0 {
|
|
||||||
return 0 // underflow
|
|
||||||
}
|
|
||||||
if exp >= mask { // overflow
|
|
||||||
if frac < 0 {
|
|
||||||
return Inf(-1)
|
|
||||||
}
|
|
||||||
return Inf(1)
|
|
||||||
}
|
|
||||||
x &^= mask << shift
|
|
||||||
x |= uint64(exp) << shift
|
|
||||||
return Float64frombits(x)
|
|
||||||
}
|
|
||||||
|
79
src/pkg/math/cbrt.go
Normal file
79
src/pkg/math/cbrt.go
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package math
|
||||||
|
|
||||||
|
/*
|
||||||
|
The algorithm is based in part on "Optimal Partitioning of
|
||||||
|
Newton's Method for Calculating Roots", by Gunter Meinardus
|
||||||
|
and G. D. Taylor, Mathematics of Computation © 1980 American
|
||||||
|
Mathematical Society.
|
||||||
|
(http://www.jstor.org/stable/2006387?seq=9, accessed 11-Feb-2010)
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Cbrt returns the cube root of its argument.
|
||||||
|
//
|
||||||
|
// Special cases are:
|
||||||
|
// Exp(+Inf) = +Inf
|
||||||
|
// Exp(-Inf) = -Inf
|
||||||
|
// Exp(NaN) = NaN
|
||||||
|
func Cbrt(x float64) float64 {
|
||||||
|
const (
|
||||||
|
A1 = 1.662848358e-01
|
||||||
|
A2 = 1.096040958e+00
|
||||||
|
A3 = 4.105032829e-01
|
||||||
|
A4 = 5.649335816e-01
|
||||||
|
B1 = 2.639607233e-01
|
||||||
|
B2 = 8.699282849e-01
|
||||||
|
B3 = 1.629083358e-01
|
||||||
|
B4 = 2.824667908e-01
|
||||||
|
C1 = 4.190115298e-01
|
||||||
|
C2 = 6.904625373e-01
|
||||||
|
C3 = 6.46502159e-02
|
||||||
|
C4 = 1.412333954e-01
|
||||||
|
)
|
||||||
|
// TODO(rsc): Remove manual inlining of IsNaN, IsInf
|
||||||
|
// when compiler does it for us
|
||||||
|
// special cases
|
||||||
|
switch {
|
||||||
|
case x != x || x < -MaxFloat64 || x > MaxFloat64: // IsNaN(x) || IsInf(x, 0):
|
||||||
|
return x
|
||||||
|
}
|
||||||
|
sign := false
|
||||||
|
if x < 0 {
|
||||||
|
x = -x
|
||||||
|
sign = true
|
||||||
|
}
|
||||||
|
// Reduce argument
|
||||||
|
f, e := Frexp(x)
|
||||||
|
m := e % 3
|
||||||
|
if m > 0 {
|
||||||
|
m -= 3
|
||||||
|
e -= m // e is multiple of 3
|
||||||
|
}
|
||||||
|
f = Ldexp(f, m) // 0.125 <= f < 1.0
|
||||||
|
|
||||||
|
// Estimate cube root
|
||||||
|
switch m {
|
||||||
|
case 0: // 0.5 <= f < 1.0
|
||||||
|
f = A1*f + A2 - A3/(A4+f)
|
||||||
|
case -1: // 0.25 <= f < 0.5
|
||||||
|
f = B1*f + B2 - B3/(B4+f)
|
||||||
|
default: // 0.125 <= f < 0.25
|
||||||
|
f = C1*f + C2 - C3/(C4+f)
|
||||||
|
}
|
||||||
|
y := Ldexp(f, e/3) // e/3 = exponent of cube root
|
||||||
|
|
||||||
|
// Iterate
|
||||||
|
s := y * y * y
|
||||||
|
t := s + x
|
||||||
|
y *= (t + x) / (s + t)
|
||||||
|
// Reiterate
|
||||||
|
s = (y*y*y - x) / x
|
||||||
|
y -= y * (((14.0/81.0)*s-(2.0/9.0))*s + (1.0 / 3.0)) * s
|
||||||
|
if sign {
|
||||||
|
y = -y
|
||||||
|
}
|
||||||
|
return y
|
||||||
|
}
|
28
src/pkg/math/frexp.go
Normal file
28
src/pkg/math/frexp.go
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package math
|
||||||
|
|
||||||
|
// Frexp breaks f into a normalized fraction
|
||||||
|
// and an integral power of two.
|
||||||
|
// It returns frac and exp satisfying f == frac × 2<sup>exp</sup>,
|
||||||
|
// with the absolute value of frac in the interval [½, 1).
|
||||||
|
func Frexp(f float64) (frac float64, exp int) {
|
||||||
|
// TODO(rsc): Remove manual inlining of IsNaN, IsInf
|
||||||
|
// when compiler does it for us
|
||||||
|
// special cases
|
||||||
|
switch {
|
||||||
|
case f == 0:
|
||||||
|
return
|
||||||
|
case f < -MaxFloat64 || f > MaxFloat64 || f != f: // IsInf(f, 0) || IsNaN(f):
|
||||||
|
frac = f
|
||||||
|
return
|
||||||
|
}
|
||||||
|
x := Float64bits(f)
|
||||||
|
exp = int((x>>shift)&mask) - bias
|
||||||
|
x &^= mask << shift
|
||||||
|
x |= bias << shift
|
||||||
|
frac = Float64frombits(x)
|
||||||
|
return
|
||||||
|
}
|
23
src/pkg/math/frexp_386.s
Normal file
23
src/pkg/math/frexp_386.s
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
// Copyright 2010 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// func Frexp(x float64) (f float64, e int)
|
||||||
|
TEXT ·Frexp(SB),7,$0
|
||||||
|
FMOVD x+0(FP), F0 // F0=x
|
||||||
|
FXAM
|
||||||
|
FSTSW AX
|
||||||
|
SAHF
|
||||||
|
JNP nan_zero_inf
|
||||||
|
JCS nan_zero_inf
|
||||||
|
FXTRACT // F0=f (0<=f<1), F1=e
|
||||||
|
FMULD $(0.5), F0 // F0=f (0.5<=f<1), F1=e
|
||||||
|
FMOVDP F0, f+8(FP) // F0=e
|
||||||
|
FLD1 // F0=1, F1=e
|
||||||
|
FADDDP F0, F1 // F0=e+1
|
||||||
|
FMOVLP F0, e+16(FP) // (int=int32)
|
||||||
|
RET
|
||||||
|
nan_zero_inf:
|
||||||
|
FMOVDP F0, f+8(FP) // F0=e
|
||||||
|
MOVL $0, e+16(FP) // e=0
|
||||||
|
RET
|
7
src/pkg/math/frexp_decl.go
Normal file
7
src/pkg/math/frexp_decl.go
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
// Copyright 2010 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package math
|
||||||
|
|
||||||
|
func Frexp(x float64) (f float64, e int)
|
30
src/pkg/math/ldexp.go
Normal file
30
src/pkg/math/ldexp.go
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package math
|
||||||
|
|
||||||
|
// Ldexp is the inverse of Frexp.
|
||||||
|
// It returns frac × 2<sup>exp</sup>.
|
||||||
|
func Ldexp(frac float64, exp int) float64 {
|
||||||
|
// TODO(rsc): Remove manual inlining of IsNaN, IsInf
|
||||||
|
// when compiler does it for us
|
||||||
|
// special cases
|
||||||
|
if frac != frac { // IsNaN(frac)
|
||||||
|
return NaN()
|
||||||
|
}
|
||||||
|
x := Float64bits(frac)
|
||||||
|
exp += int(x>>shift) & mask
|
||||||
|
if exp <= 0 {
|
||||||
|
return 0 // underflow
|
||||||
|
}
|
||||||
|
if exp >= mask { // overflow
|
||||||
|
if frac < 0 {
|
||||||
|
return Inf(-1)
|
||||||
|
}
|
||||||
|
return Inf(1)
|
||||||
|
}
|
||||||
|
x &^= mask << shift
|
||||||
|
x |= uint64(exp) << shift
|
||||||
|
return Float64frombits(x)
|
||||||
|
}
|
12
src/pkg/math/ldexp_386.s
Normal file
12
src/pkg/math/ldexp_386.s
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// Copyright 2010 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// func Ldexp(f float64, e int) float64
|
||||||
|
TEXT ·Ldexp(SB),7,$0
|
||||||
|
FMOVL e+8(FP), F0 // F0=e
|
||||||
|
FMOVD x+0(FP), F0 // F0=x, F1=e
|
||||||
|
FSCALE // F0=x*2**e, F1=e
|
||||||
|
FMOVDP F0, F1 // F0=x*2**e
|
||||||
|
FMOVDP F0, r+12(FP)
|
||||||
|
RET
|
7
src/pkg/math/ldexp_decl.go
Normal file
7
src/pkg/math/ldexp_decl.go
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
// Copyright 2010 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package math
|
||||||
|
|
||||||
|
func Ldexp(f float64, e int) float64
|
13
src/pkg/math/sincos.go
Normal file
13
src/pkg/math/sincos.go
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
// Copyright 2010 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package math
|
||||||
|
|
||||||
|
// Sincos(x) returns Sin(x), Cos(x).
|
||||||
|
//
|
||||||
|
// Special conditions are:
|
||||||
|
// Sincos(+Inf) = NaN, NaN
|
||||||
|
// Sincos(-Inf) = NaN, NaN
|
||||||
|
// Sincos(NaN) = NaN, NaN
|
||||||
|
func Sincos(x float64) (sin, cos float64) { return Sin(x), Cos(x) }
|
26
src/pkg/math/sincos_386.s
Normal file
26
src/pkg/math/sincos_386.s
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
// Copyright 2010 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// func Sincos(x float64) (sin, cos float64)
|
||||||
|
TEXT ·Sincos(SB),7,$0
|
||||||
|
FMOVD x+0(FP), F0 // F0=x
|
||||||
|
FSINCOS // F0=cos(x), F1=sin(x) if -2**63 < x < 2**63
|
||||||
|
FSTSW AX // AX=status word
|
||||||
|
ANDW $0x0400, AX
|
||||||
|
JNE 4(PC) // jump if x outside range
|
||||||
|
FMOVDP F0, c+16(FP) // F0=sin(x)
|
||||||
|
FMOVDP F0, s+8(FP)
|
||||||
|
RET
|
||||||
|
FLDPI // F0=Pi, F1=x
|
||||||
|
FADDD F0, F0 // F0=2*Pi, F1=x
|
||||||
|
FXCHD F0, F1 // F0=x, F1=2*Pi
|
||||||
|
FPREM1 // F0=reduced_x, F1=2*Pi
|
||||||
|
FSTSW AX // AX=status word
|
||||||
|
ANDW $0x0400, AX
|
||||||
|
JNE -3(PC) // jump if reduction incomplete
|
||||||
|
FMOVDP F0, F1 // F0=reduced_x
|
||||||
|
FSINCOS // F0=cos(reduced_x), F1=sin(reduced_x)
|
||||||
|
FMOVDP F0, c+16(FP) // F0=sin(reduced_x)
|
||||||
|
FMOVDP F0, s+8(FP)
|
||||||
|
RET
|
7
src/pkg/math/sincos_decl.go
Normal file
7
src/pkg/math/sincos_decl.go
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
// Copyright 2010 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package math
|
||||||
|
|
||||||
|
func Sincos(x float64) (sin, cos float64)
|
Loading…
Reference in New Issue
Block a user