欧几里得算法:
u,v都是偶数时 gcd(u, v) = 2gcd(u/2, v/2)
u,v只有一个偶数时,偶数u gcd(u, v) = gcd(u/2, v);偶数v gcd(u, v) = gcd(u, v/2)
u,v都是奇数时 gcd(u, v) = gcd((u - v)/2, v)
最大公约数代码如下:
/// <summary>
/// 计算<paramref name="a"/>和<paramref name="b"/>的最大公约数
/// </summary>
public static uint GreatestCommonDivisor(uint a, uint b)
{
if (a == 0) return b;
if (b == 0) return a;
var aZeros = a.NumberOfTrailingZeros();
var bZeros = b.NumberOfTrailingZeros();
a >>= aZeros;
b >>= bZeros;
var t = Math.Min(aZeros, bZeros);
while (a != b)
{
if (a > b)
{
a -= b;
a >>= a.NumberOfTrailingZeros();
}
else
{
b -= a;
b >>= b.NumberOfTrailingZeros();
}
}
return a << t;
}
NumberOfTrailingZeros用来计算N二进制尾数0的个数
/// <summary>
/// 返回<paramref name="n"/>的32位二进制字符串中后缀是0的个数
/// </summary>
public static int NumberOfTrailingZeros(this uint n)
{
if (n == 0) return 32;
var c = 31;
var t = n << 16; if (t != 0u) { c -= 16; n = t; }
t = n << 8; if (t != 0u) { c -= 8; n = t; }
t = n << 4; if (t != 0u) { c -= 4; n = t; }
t = n << 2; if (t != 0u) { c -= 2; n = t; }
t = n << 1; if (t != 0u) { c -= 1; }
return c;
}