扩展欧几里得算法
给定非负整数a, b,求解向量(u1, u2, u3),使得au1 + bu2 = u3 = gcd(a, b)。
扩展欧几里得算法的除法版本
引入辅助向量(v1, v2, v3),使得av1 + bv2 = v3 代码如下:
/// <summary>
/// 返回{x, y, gcd}, 使得<paramref name="a"/>x + <paramref name="b"/>y = gcd(<paramref name="a"/>, <paramref name="b"/>)
/// </summary>
public static int[] ExtendedEuclid(int a, int b)
{
if (a < 0 || b < 0)
throw new ArgumentOutOfRangeException("a and b should all be nonegative");
if (a == 0) return new int[] { 0, 1, b };
if (b == 0) return new int[] { 1, 0, a };
var aZeros = a.NumberOfTrailingZeros();
var bZeros = b.NumberOfTrailingZeros();
var k = Math.Min(aZeros, bZeros);
a >>= k; b >>= k;
var u = new int[] { 1, 0, a };
var v = new int[] { 0, 1, b };
var t = new int[3];
while(v[2] != 0)
{
var q = u[2] / v[2];
t[0] = u[0] - v[0] * q;
t[1] = u[1] - v[1] * q;
t[2] = u[2] - v[2] * q;
u[0] = v[0]; u[1] = v[1]; u[2] = v[2];
v[0] = t[0]; v[1] = t[1]; v[2] = t[2];
}
u[2] <<= k;
return u;
}
扩展欧几里得算法二进制版本
参考上述除法版本及二进制版本欧几里得算法。引入辅助向量(v1, v2, v3)。使得
av1 + bv2 = v3
在v3右移1位过程中,当v1和v2同时为偶数时,可以直接移位,否则则需要将其调整为偶数后再移位。
a(v1