Commit 22f84c5b authored by Charles L. Dorian's avatar Charles L. Dorian Committed by Russ Cox

math: more special cases for signed zero

R=rsc
CC=golang-dev
https://golang.org/cl/937042
parent d6e4e18c
This diff is collapsed.
...@@ -14,16 +14,20 @@ package math ...@@ -14,16 +14,20 @@ package math
// Asin returns the arcsine of x. // Asin returns the arcsine of x.
// //
// Special case is: // Special cases are:
// Asin(±0) = ±0
// Asin(x) = NaN if x < -1 or x > 1 // Asin(x) = NaN if x < -1 or x > 1
func Asin(x float64) float64 { func Asin(x float64) float64 {
if x == 0 {
return x // special case
}
sign := false sign := false
if x < 0 { if x < 0 {
x = -x x = -x
sign = true sign = true
} }
if x > 1 { if x > 1 {
return NaN() return NaN() // special case
} }
temp := Sqrt(1 - x*x) temp := Sqrt(1 - x*x)
......
...@@ -47,7 +47,14 @@ func satan(arg float64) float64 { ...@@ -47,7 +47,14 @@ func satan(arg float64) float64 {
} }
// Atan returns the arctangent of x. // Atan returns the arctangent of x.
//
// Special cases are:
// Atan(±0) = ±0
// Atan(±Inf) = ±Pi/2
func Atan(x float64) float64 { func Atan(x float64) float64 {
if x == 0 {
return x
}
if x > 0 { if x > 0 {
return satan(x) return satan(x)
} }
......
...@@ -15,8 +15,8 @@ package math ...@@ -15,8 +15,8 @@ package math
// Cbrt returns the cube root of its argument. // Cbrt returns the cube root of its argument.
// //
// Special cases are: // Special cases are:
// Exp(+Inf) = +Inf // Exp(±0) = ±0
// Exp(-Inf) = -Inf // Exp(±Inf) = ±Inf
// Exp(NaN) = NaN // Exp(NaN) = NaN
func Cbrt(x float64) float64 { func Cbrt(x float64) float64 {
const ( const (
...@@ -37,7 +37,7 @@ func Cbrt(x float64) float64 { ...@@ -37,7 +37,7 @@ func Cbrt(x float64) float64 {
// when compiler does it for us // when compiler does it for us
// special cases // special cases
switch { switch {
case x != x || x < -MaxFloat64 || x > MaxFloat64: // IsNaN(x) || IsInf(x, 0): case x == 0 || x != x || x < -MaxFloat64 || x > MaxFloat64: // x == 0 || IsNaN(x) || IsInf(x, 0):
return x return x
} }
sign := false sign := false
......
...@@ -11,8 +11,11 @@ package math ...@@ -11,8 +11,11 @@ package math
// Fabs(-Inf) = +Inf // Fabs(-Inf) = +Inf
// Fabs(NaN) = NaN // Fabs(NaN) = NaN
func Fabs(x float64) float64 { func Fabs(x float64) float64 {
if x < 0 { switch {
case x < 0:
return -x return -x
case x == 0:
return 0 // return correctly fabs(-0)
} }
return x return x
} }
...@@ -14,7 +14,7 @@ package math ...@@ -14,7 +14,7 @@ package math
func Floor(x float64) float64 { func Floor(x float64) float64 {
// TODO(rsc): Remove manual inlining of IsNaN, IsInf // TODO(rsc): Remove manual inlining of IsNaN, IsInf
// when compiler does it for us // when compiler does it for us
if x != x || x > MaxFloat64 || x < -MaxFloat64 { // IsNaN(x) || IsInf(x, 0) if x == 0 || x != x || x > MaxFloat64 || x < -MaxFloat64 { // x == 0 || IsNaN(x) || IsInf(x, 0)
return x return x
} }
if x < 0 { if x < 0 {
...@@ -45,7 +45,7 @@ func Ceil(x float64) float64 { return -Floor(-x) } ...@@ -45,7 +45,7 @@ func Ceil(x float64) float64 { return -Floor(-x) }
func Trunc(x float64) float64 { func Trunc(x float64) float64 {
// TODO(rsc): Remove manual inlining of IsNaN, IsInf // TODO(rsc): Remove manual inlining of IsNaN, IsInf
// when compiler does it for us // when compiler does it for us
if x != x || x > MaxFloat64 || x < -MaxFloat64 { // IsNaN(x) || IsInf(x, 0) if x == 0 || x != x || x > MaxFloat64 || x < -MaxFloat64 { // x == 0 || IsNaN(x) || IsInf(x, 0)
return x return x
} }
d, _ := Modf(x) d, _ := Modf(x)
......
...@@ -14,10 +14,9 @@ func Frexp(f float64) (frac float64, exp int) { ...@@ -14,10 +14,9 @@ func Frexp(f float64) (frac float64, exp int) {
// special cases // special cases
switch { switch {
case f == 0: case f == 0:
return return f, 0 // correctly return -0
case f < -MaxFloat64 || f > MaxFloat64 || f != f: // IsInf(f, 0) || IsNaN(f): case f < -MaxFloat64 || f > MaxFloat64 || f != f: // IsInf(f, 0) || IsNaN(f):
frac = f return f, 0
return
} }
x := Float64bits(f) x := Float64bits(f)
exp = int((x>>shift)&mask) - bias exp = int((x>>shift)&mask) - bias
......
...@@ -10,7 +10,10 @@ func Ldexp(frac float64, exp int) float64 { ...@@ -10,7 +10,10 @@ func Ldexp(frac float64, exp int) float64 {
// TODO(rsc): Remove manual inlining of IsNaN, IsInf // TODO(rsc): Remove manual inlining of IsNaN, IsInf
// when compiler does it for us // when compiler does it for us
// special cases // special cases
if frac != frac { // IsNaN(frac) switch {
case frac == 0:
return frac // correctly return -0
case frac != frac: // IsNaN(frac):
return NaN() return NaN()
} }
x := Float64bits(frac) x := Float64bits(frac)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment