有人知道编译时计算C中至少两个数字的LCM (最小公共倍数)和/或GCD (最大公共分母)的机制吗?
我通常使用GCC,并回顾它可以在编译时计算所有输入的特定值(例如: sin、cos等.)。
我正在寻找如何在GCC中这样做(最好是以其他编译器可以处理的方式),并希望同样的机制能在Visual中工作。
发布于 2008-09-16 20:37:03
毕竟我想出来了..。
#define GCD(a,b) ((a>=b)*GCD_1(a,b)+(a<b)*GCD_1(b,a))
#define GCD_1(a,b) ((((!(b)))*(a)) + (!!(b))*GCD_2((b), (a)%((b)+!(b))))
#define GCD_2(a,b) ((((!(b)))*(a)) + (!!(b))*GCD_3((b), (a)%((b)+!(b))))
#define GCD_3(a,b) ((((!(b)))*(a)) + (!!(b))*GCD_4((b), (a)%((b)+!(b))))
#define GCD_4(a,b) ((((!(b)))*(a)) + (!!(b))*GCD_5((b), (a)%((b)+!(b))))
#define GCD_5(a,b) ((((!(b)))*(a)) + (!!(b))*GCD_6((b), (a)%((b)+!(b))))
#define GCD_6(a,b) ((((!(b)))*(a)) + (!!(b))*GCD_7((b), (a)%((b)+!(b))))
#define GCD_7(a,b) ((((!(b)))*(a)) + (!!(b))*GCD_8((b), (a)%((b)+!(b))))
#define GCD_8(a,b) ((((!(b)))*(a)) + (!!(b))*GCD_last((b), (a)%((b)+!(b))))
#define GCD_last(a,b) (a)
#define LCM(a,b) (((a)*(b))/GCD(a,b))
int main()
{
printf("%d, %d\n", GCD(21,6), LCM(21,6));
return 0;
}注意,根据整数的大小,可能需要包含更多的中间步骤(即GCD_9、GCD_10等.)。
我希望这能帮到你!
发布于 2008-09-17 01:01:38
部分基于Kevin的答案,这里有一个宏序列,对于常量值和运行时错误有编译时失败的情况。
如果失败不是选项,也可以将其配置为引入非编译时函数。
#define GCD(a,b) ( ((a) > (b)) ? ( GCD_1((a), (b)) ) : ( GCD_1((b), (a)) ) )
#define GCD_1(a,b) ( ((b) == 0) ? (a) : GCD_2((b), (a) % (b) ) )
#define GCD_2(a,b) ( ((b) == 0) ? (a) : GCD_3((b), (a) % (b) ) )
#define GCD_3(a,b) ( ((b) == 0) ? (a) : GCD_4((b), (a) % (b) ) )
#define GCD_4(a,b) ( ((b) == 0) ? (a) : GCD_5((b), (a) % (b) ) )
#define GCD_5(a,b) ( ((b) == 0) ? (a) : GCD_6((b), (a) % (b) ) )
#define GCD_6(a,b) ( ((b) == 0) ? (a) : GCD_7((b), (a) % (b) ) )
#define GCD_7(a,b) ( ((b) == 0) ? (a) : GCD_8((b), (a) % (b) ) )
#define GCD_8(a,b) ( ((b) == 0) ? (a) : GCD_9((b), (a) % (b) ) )
#define GCD_9(a,b) (assert(0),-1)请注意,扩展过大,即使它会提前终止,因为编译器必须在计算之前完全插入所有内容。
发布于 2008-09-16 22:04:14
我意识到您对C实现只感兴趣,但我想无论如何我还是会对C++和模板元编程进行评论。我并不完全相信在C++中它是可能的,因为您需要定义好的初始条件才能终止递归扩展。
template<int A, int B>
struct GCD {
enum { value = GCD<B, A % B>::value };
};
/*
Because GCD terminates when only one of the values is zero it is impossible to define a base condition to satisfy all GCD<N, 0>::value conditions
*/
template<>
struct GCD<A, 0> { // This is obviously not legal
enum { value = A };
};
int main(void)
{
::printf("gcd(%d, %d) = %d", 7, 35, GCD<7, 35>::value);
}但是,在C++0x中,这是可能的,但%100肯定是不可能的。
https://stackoverflow.com/questions/76334
复制相似问题