我有一个算法,它很大程度上基于使用有符号整数的最大公约数,所以我试图让它更快。请不要告诉我这种优化是不必要的,因为我已经将性能提高了 50%。我没有看到任何优化的潜力,但我可能错了。
在以下代码中,断言 b != 0
Integer gcd(Integer a, Integer b)
{
if ( a == 0 )
{
return b;
}
if ( a == b )
{
return a;
}
const Integer mask_a = (a >> (sizeof(Integer) * 8 - 1));
a = (a + mask_a) ^ mask_a; // a = |a|
const Integer mask_b = (b >> (sizeof(Integer) * 8 - 1));
b = (b + mask_b) ^ mask_b; // b = |b|
if ( ~a & 1 )
{
if ( b & 1 )
{
// 2 divides a but not b
return gcd(a >> 1, b);
}
else
{
// both a and b are divisible by 2, thus gcd(a, b) == 2 * gcd( a / 2, b / 2)
return gcd(a >> 1, b >> 1) << 1;
}
}
if ( ~b & 1 )
{
// 2 divides b, but not a
return gcd(a, b >> 1);
}
if ( a > b )
{
// since both a and b are odd, a - b is divisible by 2
// gcd(a, b) == gcd( a - b, b)
return gcd((a - b) >> 1, b);
}
else
{
// since both a and b are odd, a - b is divisible by 2
// gcd(a, b) == gcd( a - b, b)
return gcd((b - a) >> 1, a);
}
}
附带说明:整数是int
,long
或long long
. 它是上面某处的typedef。
如您所见,在将 a 和 b 带到其各自的绝对值方面进行了优化,这在我的机器上运行良好(不一定在所有 afaik 上)。我有点不喜欢分支混乱。有什么方法可以改善吗?