math: correct result for Pow(x, ±.5)

Fixes #23224

The previous Pow code had an optimization for
powers equal to ±0.5 that used Sqrt for
increased accuracy/speed.  This caused special
cases involving powers of ±0.5 to disagree with
the Pow spec.  This change places the Sqrt optimization
after all of the special case handling.

Change-Id: I6bf757f6248256b29cc21725a84e27705d855369
Reviewed-on: https://go-review.googlesource.com/85660
Reviewed-by: Robert Griesemer <gri@golang.org>
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
Brian Kessler 2017-12-30 01:27:28 -07:00 committed by Robert Griesemer
parent 6317adeed7
commit 5305bdd86b
2 changed files with 10 additions and 4 deletions

View file

@ -1589,6 +1589,7 @@ var vfpowSC = [][2]float64{
{Inf(-1), 1},
{Inf(-1), 3},
{Inf(-1), Pi},
{Inf(-1), 0.5},
{Inf(-1), NaN()},
{-Pi, Inf(-1)},
@ -1607,9 +1608,11 @@ var vfpowSC = [][2]float64{
{-1 / 2, Inf(1)},
{Copysign(0, -1), Inf(-1)},
{Copysign(0, -1), -Pi},
{Copysign(0, -1), -0.5},
{Copysign(0, -1), -3},
{Copysign(0, -1), 3},
{Copysign(0, -1), Pi},
{Copysign(0, -1), 0.5},
{Copysign(0, -1), Inf(1)},
{0, Inf(-1)},
@ -1666,6 +1669,7 @@ var powSC = []float64{
Inf(-1), // pow(-Inf, 1)
Inf(-1), // pow(-Inf, 3)
Inf(1), // pow(-Inf, Pi)
Inf(1), // pow(-Inf, 0.5)
NaN(), // pow(-Inf, NaN)
0, // pow(-Pi, -Inf)
NaN(), // pow(-Pi, -Pi)
@ -1682,9 +1686,11 @@ var powSC = []float64{
0, // pow(-1/2, +Inf)
Inf(1), // pow(-0, -Inf)
Inf(1), // pow(-0, -Pi)
Inf(1), // pow(-0, -0.5)
Inf(-1), // pow(-0, -3) IEEE 754-2008
Copysign(0, -1), // pow(-0, 3) IEEE 754-2008
0, // pow(-0, +Pi)
0, // pow(-0, 0.5)
0, // pow(-0, +Inf)
Inf(1), // pow(+0, -Inf)
Inf(1), // pow(+0, -Pi)

View file

@ -43,10 +43,6 @@ func pow(x, y float64) float64 {
return 1
case y == 1:
return x
case y == 0.5:
return Sqrt(x)
case y == -0.5:
return 1 / Sqrt(x)
case IsNaN(x) || IsNaN(y):
return NaN()
case x == 0:
@ -81,6 +77,10 @@ func pow(x, y float64) float64 {
case y > 0:
return Inf(1)
}
case y == 0.5:
return Sqrt(x)
case y == -0.5:
return 1 / Sqrt(x)
}
absy := y