Commit f4240666 authored by Robert Griesemer's avatar Robert Griesemer

math/big: fix binaryGCD

R=rsc
CC=golang-dev
https://golang.org/cl/6297085
parent b7c5e23d
...@@ -643,12 +643,13 @@ func (z *Int) GCD(x, y, a, b *Int) *Int { ...@@ -643,12 +643,13 @@ func (z *Int) GCD(x, y, a, b *Int) *Int {
return z return z
} }
// binaryGCD sets z to the greatest common divisor of a and b, which must be // binaryGCD sets z to the greatest common divisor of a and b, which both must
// positive, and returns z. // be > 0, and returns z.
// See Knuth, The Art of Computer Programming, Vol. 2, Section 4.5.2, Algorithm B. // See Knuth, The Art of Computer Programming, Vol. 2, Section 4.5.2, Algorithm B.
func (z *Int) binaryGCD(a, b *Int) *Int { func (z *Int) binaryGCD(a, b *Int) *Int {
u := z u := z
v := new(Int) v := new(Int)
// use one Euclidean iteration to ensure that u and v are approx. the same size // use one Euclidean iteration to ensure that u and v are approx. the same size
switch { switch {
case len(a.abs) > len(b.abs): case len(a.abs) > len(b.abs):
...@@ -662,6 +663,12 @@ func (z *Int) binaryGCD(a, b *Int) *Int { ...@@ -662,6 +663,12 @@ func (z *Int) binaryGCD(a, b *Int) *Int {
v.Set(b) 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 // determine largest k such that u = u' << k, v = v' << k
k := u.abs.trailingZeroBits() k := u.abs.trailingZeroBits()
if vk := v.abs.trailingZeroBits(); vk < k { if vk := v.abs.trailingZeroBits(); vk < k {
......
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