From f4240666be0a267b4e5c793b795e9af11b080e9f Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Wed, 13 Jun 2012 10:29:06 -0700 Subject: [PATCH] math/big: fix binaryGCD R=rsc CC=golang-dev https://golang.org/cl/6297085 --- src/pkg/math/big/int.go | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/pkg/math/big/int.go b/src/pkg/math/big/int.go index 16fd9bfa98b..74e5c2313b1 100644 --- a/src/pkg/math/big/int.go +++ b/src/pkg/math/big/int.go @@ -643,12 +643,13 @@ func (z *Int) GCD(x, y, a, b *Int) *Int { return z } -// binaryGCD sets z to the greatest common divisor of a and b, which must be -// positive, and returns z. +// binaryGCD sets z to the greatest common divisor of a and b, which both must +// be > 0, and returns z. // See Knuth, The Art of Computer Programming, Vol. 2, Section 4.5.2, Algorithm B. func (z *Int) binaryGCD(a, b *Int) *Int { u := z v := new(Int) + // use one Euclidean iteration to ensure that u and v are approx. the same size switch { case len(a.abs) > len(b.abs): @@ -662,6 +663,12 @@ func (z *Int) binaryGCD(a, b *Int) *Int { v.Set(b) } + // v might be 0 now + if len(v.abs) == 0 { + return u + } + // u > 0 && v > 0 + // determine largest k such that u = u' << k, v = v' << k k := u.abs.trailingZeroBits() if vk := v.abs.trailingZeroBits(); vk < k {