mirror of
https://github.com/golang/go
synced 2024-11-25 11:07:59 -07:00
math: special cases for Ceil, Exp, Floor, Log, Log10
Added special case tests to all_test.go. Added tests to Floor, in-lined tests in Exp and Log. R=rsc CC=golang-dev https://golang.org/cl/184081
This commit is contained in:
parent
e7cceb85e4
commit
46206c52e3
@ -118,6 +118,18 @@ var log = []float64{
|
|||||||
6.0174879014578053e-01,
|
6.0174879014578053e-01,
|
||||||
2.1617038728473527e+00,
|
2.1617038728473527e+00,
|
||||||
}
|
}
|
||||||
|
var log10 = []float64{
|
||||||
|
6.9714316642508291e-01,
|
||||||
|
8.8867769017393205e-01,
|
||||||
|
-5.5770832400658930e-01,
|
||||||
|
6.9989004768229943e-01,
|
||||||
|
9.8391002850684232e-01,
|
||||||
|
4.6633031029295153e-01,
|
||||||
|
7.1842557117242328e-01,
|
||||||
|
4.3583479968917772e-01,
|
||||||
|
2.6133617905227037e-01,
|
||||||
|
9.3881606348649405e-01,
|
||||||
|
}
|
||||||
var pow = []float64{
|
var pow = []float64{
|
||||||
9.5282232631648415e+04,
|
9.5282232631648415e+04,
|
||||||
5.4811599352999900e+07,
|
5.4811599352999900e+07,
|
||||||
@ -210,6 +222,28 @@ var atanSC = []float64{
|
|||||||
NaN(),
|
NaN(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var vfceilSC = []float64{
|
||||||
|
Inf(-1),
|
||||||
|
Inf(1),
|
||||||
|
NaN(),
|
||||||
|
}
|
||||||
|
var ceilSC = []float64{
|
||||||
|
Inf(-1),
|
||||||
|
Inf(1),
|
||||||
|
NaN(),
|
||||||
|
}
|
||||||
|
|
||||||
|
var vfexpSC = []float64{
|
||||||
|
Inf(-1),
|
||||||
|
Inf(1),
|
||||||
|
NaN(),
|
||||||
|
}
|
||||||
|
var expSC = []float64{
|
||||||
|
0,
|
||||||
|
Inf(1),
|
||||||
|
NaN(),
|
||||||
|
}
|
||||||
|
|
||||||
var vffmodSC = [][2]float64{
|
var vffmodSC = [][2]float64{
|
||||||
[2]float64{Inf(-1), Inf(-1)},
|
[2]float64{Inf(-1), Inf(-1)},
|
||||||
[2]float64{Inf(-1), -Pi},
|
[2]float64{Inf(-1), -Pi},
|
||||||
@ -275,6 +309,21 @@ var fmodSC = []float64{
|
|||||||
NaN(),
|
NaN(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var vflogSC = []float64{
|
||||||
|
Inf(-1),
|
||||||
|
-Pi,
|
||||||
|
0,
|
||||||
|
Inf(1),
|
||||||
|
NaN(),
|
||||||
|
}
|
||||||
|
var logSC = []float64{
|
||||||
|
NaN(),
|
||||||
|
NaN(),
|
||||||
|
Inf(-1),
|
||||||
|
Inf(1),
|
||||||
|
NaN(),
|
||||||
|
}
|
||||||
|
|
||||||
var vfpowSC = [][2]float64{
|
var vfpowSC = [][2]float64{
|
||||||
[2]float64{-Pi, Pi},
|
[2]float64{-Pi, Pi},
|
||||||
[2]float64{-Pi, -Pi},
|
[2]float64{-Pi, -Pi},
|
||||||
@ -440,6 +489,11 @@ func TestCeil(t *testing.T) {
|
|||||||
t.Errorf("Ceil(%g) = %g, want %g\n", vf[i], f, ceil[i])
|
t.Errorf("Ceil(%g) = %g, want %g\n", vf[i], f, ceil[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for i := 0; i < len(vfceilSC); i++ {
|
||||||
|
if f := Ceil(vfceilSC[i]); !alike(ceilSC[i], f) {
|
||||||
|
t.Errorf("Ceil(%g) = %g, want %g\n", vfceilSC[i], f, ceilSC[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestExp(t *testing.T) {
|
func TestExp(t *testing.T) {
|
||||||
@ -448,6 +502,11 @@ func TestExp(t *testing.T) {
|
|||||||
t.Errorf("Exp(%g) = %g, want %g\n", vf[i], f, exp[i])
|
t.Errorf("Exp(%g) = %g, want %g\n", vf[i], f, exp[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for i := 0; i < len(vfexpSC); i++ {
|
||||||
|
if f := Exp(vfexpSC[i]); !alike(expSC[i], f) {
|
||||||
|
t.Errorf("Exp(%g) = %g, want %g\n", vfexpSC[i], f, expSC[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFloor(t *testing.T) {
|
func TestFloor(t *testing.T) {
|
||||||
@ -456,6 +515,11 @@ func TestFloor(t *testing.T) {
|
|||||||
t.Errorf("Floor(%g) = %g, want %g\n", vf[i], f, floor[i])
|
t.Errorf("Floor(%g) = %g, want %g\n", vf[i], f, floor[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for i := 0; i < len(vfceilSC); i++ {
|
||||||
|
if f := Floor(vfceilSC[i]); !alike(ceilSC[i], f) {
|
||||||
|
t.Errorf("Floor(%g) = %g, want %g\n", vfceilSC[i], f, ceilSC[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFmod(t *testing.T) {
|
func TestFmod(t *testing.T) {
|
||||||
@ -479,7 +543,29 @@ func TestLog(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if f := Log(10); f != Ln10 {
|
if f := Log(10); f != Ln10 {
|
||||||
t.Errorf("Log(%g) = %g, want %g\n", 10, f, Ln10)
|
t.Errorf("Log(%g) = %g, want %g\n", 10.0, f, Ln10)
|
||||||
|
}
|
||||||
|
for i := 0; i < len(vflogSC); i++ {
|
||||||
|
if f := Log(vflogSC[i]); !alike(logSC[i], f) {
|
||||||
|
t.Errorf("Log(%g) = %g, want %g\n", vflogSC[i], f, logSC[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLog10(t *testing.T) {
|
||||||
|
for i := 0; i < len(vf); i++ {
|
||||||
|
a := Fabs(vf[i])
|
||||||
|
if f := Log10(a); !veryclose(log10[i], f) {
|
||||||
|
t.Errorf("Log10(%g) = %g, want %g\n", a, f, log10[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if f := Log10(E); f != Log10E {
|
||||||
|
t.Errorf("Log10(%g) = %g, want %g\n", E, f, Log10E)
|
||||||
|
}
|
||||||
|
for i := 0; i < len(vflogSC); i++ {
|
||||||
|
if f := Log10(vflogSC[i]); !alike(logSC[i], f) {
|
||||||
|
t.Errorf("Log10(%g) = %g, want %g\n", vflogSC[i], f, logSC[i])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,11 +104,13 @@ func Exp(x float64) float64 {
|
|||||||
NearZero = 1.0 / (1 << 28) // 2^-28
|
NearZero = 1.0 / (1 << 28) // 2^-28
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// TODO(rsc): Remove manual inlining of IsNaN, IsInf
|
||||||
|
// when compiler does it for us
|
||||||
// special cases
|
// special cases
|
||||||
switch {
|
switch {
|
||||||
case IsNaN(x) || IsInf(x, 1):
|
case x != x || x > MaxFloat64: // IsNaN(x) || IsInf(x, 1):
|
||||||
return x
|
return x
|
||||||
case IsInf(x, -1):
|
case x < -MaxFloat64: // IsInf(x, -1):
|
||||||
return 0
|
return 0
|
||||||
case x > Overflow:
|
case x > Overflow:
|
||||||
return Inf(1)
|
return Inf(1)
|
||||||
|
@ -6,7 +6,15 @@ package math
|
|||||||
|
|
||||||
|
|
||||||
// Floor returns the greatest integer value less than or equal to x.
|
// Floor returns the greatest integer value less than or equal to x.
|
||||||
|
//
|
||||||
|
// Special cases are:
|
||||||
|
// Floor(+Inf) = +Inf
|
||||||
|
// Floor(-Inf) = -Inf
|
||||||
|
// Floor(NaN) = NaN
|
||||||
func Floor(x float64) float64 {
|
func Floor(x float64) float64 {
|
||||||
|
if x != x || x > MaxFloat64 || x < -MaxFloat64 { // IsNaN(x) || IsInf(x, 0)
|
||||||
|
return x
|
||||||
|
}
|
||||||
if x < 0 {
|
if x < 0 {
|
||||||
d, fract := Modf(-x)
|
d, fract := Modf(-x)
|
||||||
if fract != 0.0 {
|
if fract != 0.0 {
|
||||||
@ -19,4 +27,9 @@ func Floor(x float64) float64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Ceil returns the least integer value greater than or equal to x.
|
// Ceil returns the least integer value greater than or equal to x.
|
||||||
|
//
|
||||||
|
// Special cases are:
|
||||||
|
// Ceil(+Inf) = +Inf
|
||||||
|
// Ceil(-Inf) = -Inf
|
||||||
|
// Ceil(NaN) = NaN
|
||||||
func Ceil(x float64) float64 { return -Floor(-x) }
|
func Ceil(x float64) float64 { return -Floor(-x) }
|
||||||
|
@ -90,9 +90,11 @@ func Log(x float64) float64 {
|
|||||||
L7 = 1.479819860511658591e-01 /* 3FC2F112 DF3E5244 */
|
L7 = 1.479819860511658591e-01 /* 3FC2F112 DF3E5244 */
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// TODO(rsc): Remove manual inlining of IsNaN, IsInf
|
||||||
|
// when compiler does it for us
|
||||||
// special cases
|
// special cases
|
||||||
switch {
|
switch {
|
||||||
case IsNaN(x) || IsInf(x, 1):
|
case x != x || x > MaxFloat64: // IsNaN(x) || IsInf(x, 1):
|
||||||
return x
|
return x
|
||||||
case x < 0:
|
case x < 0:
|
||||||
return NaN()
|
return NaN()
|
||||||
@ -122,9 +124,4 @@ func Log(x float64) float64 {
|
|||||||
|
|
||||||
// Log10 returns the decimal logarithm of x.
|
// Log10 returns the decimal logarithm of x.
|
||||||
// The special cases are the same as for Log.
|
// The special cases are the same as for Log.
|
||||||
func Log10(x float64) float64 {
|
func Log10(x float64) float64 { return Log(x) * (1 / Ln10) }
|
||||||
if x <= 0 {
|
|
||||||
return NaN()
|
|
||||||
}
|
|
||||||
return Log(x) * (1 / Ln10)
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user