]> Cypherpunks repositories - gostls13.git/commitdiff
math: fix Pow10 loop
authorVolker Dobler <dr.volker.dobler@gmail.com>
Wed, 24 Aug 2011 17:59:52 +0000 (13:59 -0400)
committerRuss Cox <rsc@golang.org>
Wed, 24 Aug 2011 17:59:52 +0000 (13:59 -0400)
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

src/pkg/math/all_test.go
src/pkg/math/pow10.go

index d2a7d411ec010d8bc511715a481fc7de5756f544..1fe4513c18375ab150cd292ce1f3c2da5ae4bf89 100644 (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)
index bda2e824ef1c3d58c4ce3072456a62796e5b73a0..20f91bcb70cf281a13022d5ae3a7e931a23be113 100644 (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)
        }