]> Cypherpunks.ru repositories - gostls13.git/commitdiff
math/big: don't clobber shared underlying array in pow5 computation
authorRobert Griesemer <gri@golang.org>
Thu, 4 Apr 2019 00:12:27 +0000 (17:12 -0700)
committerRobert Griesemer <gri@golang.org>
Mon, 15 Apr 2019 17:48:21 +0000 (17:48 +0000)
Rearranged code slightly to make lifetime of underlying array of
pow5 more explicit in code.

Fixes #31184.

Change-Id: I063081f0e54097c499988d268a23813746592654
Reviewed-on: https://go-review.googlesource.com/c/go/+/170641
Reviewed-by: Filippo Valsorda <filippo@golang.org>
src/math/big/ratconv.go
src/math/big/ratconv_test.go

index 3ea03d5c615778e6517517ff7b1b004e1bb91ac2..f29ec98cdcb54a6b14b2d0aafa52e50710d76bab 100644 (file)
@@ -162,36 +162,31 @@ func (z *Rat) SetString(s string) (*Rat, bool) {
        }
        // exp consumed - not needed anymore
 
-       // compute pow5 if needed
-       pow5 := z.b.abs
+       // apply exp5 contributions
+       // (start with exp5 so the numbers to multiply are smaller)
        if exp5 != 0 {
                n := exp5
                if n < 0 {
                        n = -n
                }
-               pow5 = pow5.expNN(natFive, nat(nil).setWord(Word(n)), nil)
+               pow5 := z.b.abs.expNN(natFive, nat(nil).setWord(Word(n)), nil) // use underlying array of z.b.abs
+               if exp5 > 0 {
+                       z.a.abs = z.a.abs.mul(z.a.abs, pow5)
+                       z.b.abs = z.b.abs.setWord(1)
+               } else {
+                       z.b.abs = pow5
+               }
+       } else {
+               z.b.abs = z.b.abs.setWord(1)
        }
 
-       // apply dividend contributions of exponents
-       // (start with exp5 so the numbers to multiply are smaller)
-       if exp5 > 0 {
-               z.a.abs = z.a.abs.mul(z.a.abs, pow5)
-               exp5 = 0
-       }
+       // apply exp2 contributions
        if exp2 > 0 {
                if int64(uint(exp2)) != exp2 {
                        panic("exponent too large")
                }
                z.a.abs = z.a.abs.shl(z.a.abs, uint(exp2))
-               exp2 = 0
-       }
-
-       // apply divisor contributions of exponents
-       z.b.abs = z.b.abs.setWord(1)
-       if exp5 < 0 {
-               z.b.abs = pow5
-       }
-       if exp2 < 0 {
+       } else if exp2 < 0 {
                if int64(uint(-exp2)) != -exp2 {
                        panic("exponent too large")
                }
index 87ee9fa972aa265f18b6a12540e5b2c3d6f16601..ba0d1ba9e11580d0cd340f40bc17d7a61a20fb36 100644 (file)
@@ -574,3 +574,18 @@ func TestFloat64SpecialCases(t *testing.T) {
                }
        }
 }
+
+func TestIssue31184(t *testing.T) {
+       var x Rat
+       for _, want := range []string{
+               "-213.090",
+               "8.192",
+               "16.000",
+       } {
+               x.SetString(want)
+               got := x.FloatString(3)
+               if got != want {
+                       t.Errorf("got %s, want %s", got, want)
+               }
+       }
+}