1
0
mirror of https://github.com/golang/go synced 2024-11-25 08:47: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:
Volker Dobler 2011-08-24 13:59:52 -04:00 committed by Russ Cox
parent 80f79ad305
commit f78e7d36a6
2 changed files with 40 additions and 0 deletions

View File

@ -1359,6 +1359,20 @@ var powSC = []float64{
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{
Inf(-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) {
for i := 0; i < len(vf); i++ {
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) {
for i := 0; i < b.N; i++ {
Remainder(10, 3)

View File

@ -10,6 +10,12 @@ var pow10tab [70]float64
// Pow10 returns 10**e, the base-10 exponential of e.
func Pow10(e int) float64 {
if e <= -325 {
return 0
} else if e > 309 {
return Inf(1)
}
if e < 0 {
return 1 / Pow10(-e)
}