mirror of
https://github.com/golang/go
synced 2024-11-25 16:07:56 -07:00
math: fix Pow10 loop
Pow10 failed for MinInt32 (endless loop until out of memory). Fix by returning 0 and +Inf for all arguments where the result is not representable in a float64. Fixes #2159. R=rsc CC=golang-dev https://golang.org/cl/4930041
This commit is contained in:
parent
80f79ad305
commit
f78e7d36a6
@ -1359,6 +1359,20 @@ var powSC = []float64{
|
|||||||
NaN(), // pow(NaN, NaN)
|
NaN(), // pow(NaN, NaN)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var vfpow10SC = []int{
|
||||||
|
MinInt32,
|
||||||
|
MaxInt32,
|
||||||
|
-325,
|
||||||
|
309,
|
||||||
|
}
|
||||||
|
|
||||||
|
var pow10SC = []float64{
|
||||||
|
0, // pow10(MinInt32)
|
||||||
|
Inf(1), // pow10(MaxInt32)
|
||||||
|
0, // pow10(-325)
|
||||||
|
Inf(1), // pow10(309)
|
||||||
|
}
|
||||||
|
|
||||||
var vfsignbitSC = []float64{
|
var vfsignbitSC = []float64{
|
||||||
Inf(-1),
|
Inf(-1),
|
||||||
Copysign(0, -1),
|
Copysign(0, -1),
|
||||||
@ -2143,6 +2157,14 @@ func TestPow(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPow10(t *testing.T) {
|
||||||
|
for i := 0; i < len(vfpow10SC); i++ {
|
||||||
|
if f := Pow10(vfpow10SC[i]); !alike(pow10SC[i], f) {
|
||||||
|
t.Errorf("Pow10(%d) = %g, want %g", vfpow10SC[i], f, pow10SC[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestRemainder(t *testing.T) {
|
func TestRemainder(t *testing.T) {
|
||||||
for i := 0; i < len(vf); i++ {
|
for i := 0; i < len(vf); i++ {
|
||||||
if f := Remainder(10, vf[i]); remainder[i] != f {
|
if f := Remainder(10, vf[i]); remainder[i] != f {
|
||||||
@ -2659,6 +2681,18 @@ func BenchmarkPowFrac(b *testing.B) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func BenchmarkPow10Pos(b *testing.B) {
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
Pow10(300)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkPow10Neg(b *testing.B) {
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
Pow10(-300)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func BenchmarkRemainder(b *testing.B) {
|
func BenchmarkRemainder(b *testing.B) {
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
Remainder(10, 3)
|
Remainder(10, 3)
|
||||||
|
@ -10,6 +10,12 @@ var pow10tab [70]float64
|
|||||||
|
|
||||||
// Pow10 returns 10**e, the base-10 exponential of e.
|
// Pow10 returns 10**e, the base-10 exponential of e.
|
||||||
func Pow10(e int) float64 {
|
func Pow10(e int) float64 {
|
||||||
|
if e <= -325 {
|
||||||
|
return 0
|
||||||
|
} else if e > 309 {
|
||||||
|
return Inf(1)
|
||||||
|
}
|
||||||
|
|
||||||
if e < 0 {
|
if e < 0 {
|
||||||
return 1 / Pow10(-e)
|
return 1 / Pow10(-e)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user