1
0
mirror of https://github.com/golang/go synced 2024-11-19 13:24:42 -07:00
go/src/math/sincos.go
Ilya Tocar bc6459ac6c math: remove asm version of sincos everywhere, except 386
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>
2017-04-24 15:09:18 +00:00

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
}