mirror of
https://github.com/golang/go
synced 2024-11-19 13:24:42 -07:00
bc6459ac6c
We have dedicated asm implementation of sincos only on 386 and amd64, on everything else we are just jumping to generic version. However amd64 version is actually slower than generic one: Sincos-6 34.4ns ± 0% 24.8ns ± 0% -27.79% (p=0.000 n=8+10) So remove all sincos*.s and keep only generic and 386. Updates #19819 Change-Id: I7eefab35743729578264f52f6d23ee2c227c92a5 Reviewed-on: https://go-review.googlesource.com/41200 Run-TryBot: Ilya Tocar <ilya.tocar@intel.com> Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
70 lines
1.8 KiB
Go
70 lines
1.8 KiB
Go
// 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.
|
|
|
|
// +build !386
|
|
|
|
package math
|
|
|
|
// Coefficients _sin[] and _cos[] are found in pkg/math/sin.go.
|
|
|
|
// Sincos returns Sin(x), Cos(x).
|
|
//
|
|
// Special cases are:
|
|
// Sincos(±0) = ±0, 1
|
|
// Sincos(±Inf) = NaN, NaN
|
|
// Sincos(NaN) = NaN, NaN
|
|
func Sincos(x float64) (sin, cos float64) {
|
|
const (
|
|
PI4A = 7.85398125648498535156E-1 // 0x3fe921fb40000000, Pi/4 split into three parts
|
|
PI4B = 3.77489470793079817668E-8 // 0x3e64442d00000000,
|
|
PI4C = 2.69515142907905952645E-15 // 0x3ce8469898cc5170,
|
|
M4PI = 1.273239544735162542821171882678754627704620361328125 // 4/pi
|
|
)
|
|
// special cases
|
|
switch {
|
|
case x == 0:
|
|
return x, 1 // return ±0.0, 1.0
|
|
case IsNaN(x) || IsInf(x, 0):
|
|
return NaN(), NaN()
|
|
}
|
|
|
|
// make argument positive
|
|
sinSign, cosSign := false, false
|
|
if x < 0 {
|
|
x = -x
|
|
sinSign = true
|
|
}
|
|
|
|
j := int64(x * M4PI) // integer part of x/(Pi/4), as integer for tests on the phase angle
|
|
y := float64(j) // integer part of x/(Pi/4), as float
|
|
|
|
if j&1 == 1 { // map zeros to origin
|
|
j++
|
|
y++
|
|
}
|
|
j &= 7 // octant modulo 2Pi radians (360 degrees)
|
|
if j > 3 { // reflect in x axis
|
|
j -= 4
|
|
sinSign, cosSign = !sinSign, !cosSign
|
|
}
|
|
if j > 1 {
|
|
cosSign = !cosSign
|
|
}
|
|
|
|
z := ((x - y*PI4A) - y*PI4B) - y*PI4C // Extended precision modular arithmetic
|
|
zz := z * z
|
|
cos = 1.0 - 0.5*zz + zz*zz*((((((_cos[0]*zz)+_cos[1])*zz+_cos[2])*zz+_cos[3])*zz+_cos[4])*zz+_cos[5])
|
|
sin = z + z*zz*((((((_sin[0]*zz)+_sin[1])*zz+_sin[2])*zz+_sin[3])*zz+_sin[4])*zz+_sin[5])
|
|
if j == 1 || j == 2 {
|
|
sin, cos = cos, sin
|
|
}
|
|
if cosSign {
|
|
cos = -cos
|
|
}
|
|
if sinSign {
|
|
sin = -sin
|
|
}
|
|
return
|
|
}
|