Commit f8c6f986 authored by Robert Griesemer's avatar Robert Griesemer

math/big: don't clobber shared underlying array in pow5 computation

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/+/170641Reviewed-by: default avatarFilippo Valsorda <filippo@golang.org>
parent 97c4ad43
...@@ -162,36 +162,31 @@ func (z *Rat) SetString(s string) (*Rat, bool) { ...@@ -162,36 +162,31 @@ func (z *Rat) SetString(s string) (*Rat, bool) {
} }
// exp consumed - not needed anymore // exp consumed - not needed anymore
// compute pow5 if needed // apply exp5 contributions
pow5 := z.b.abs // (start with exp5 so the numbers to multiply are smaller)
if exp5 != 0 { if exp5 != 0 {
n := exp5 n := exp5
if n < 0 { if n < 0 {
n = -n 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 // apply exp2 contributions
// (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
}
if exp2 > 0 { if exp2 > 0 {
if int64(uint(exp2)) != exp2 { if int64(uint(exp2)) != exp2 {
panic("exponent too large") panic("exponent too large")
} }
z.a.abs = z.a.abs.shl(z.a.abs, uint(exp2)) z.a.abs = z.a.abs.shl(z.a.abs, uint(exp2))
exp2 = 0 } else if 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 {
if int64(uint(-exp2)) != -exp2 { if int64(uint(-exp2)) != -exp2 {
panic("exponent too large") panic("exponent too large")
} }
......
...@@ -574,3 +574,18 @@ func TestFloat64SpecialCases(t *testing.T) { ...@@ -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)
}
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment