首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >编译时LCM / GCD

编译时LCM / GCD
EN

Stack Overflow用户
提问于 2008-09-16 20:03:33
回答 4查看 2.6K关注 0票数 3

有人知道编译时计算C中至少两个数字的LCM (最小公共倍数)和/或GCD (最大公共分母)的机制吗?

我通常使用GCC,并回顾它可以在编译时计算所有输入的特定值(例如: sin、cos等.)。

我正在寻找如何在GCC中这样做(最好是以其他编译器可以处理的方式),并希望同样的机制能在Visual中工作。

EN

回答 4

Stack Overflow用户

发布于 2008-09-16 20:37:03

毕竟我想出来了..。

代码语言:javascript
复制
#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等.)。

我希望这能帮到你!

票数 6
EN

Stack Overflow用户

发布于 2008-09-17 01:01:38

部分基于Kevin的答案,这里有一个宏序列,对于常量值和运行时错误有编译时失败的情况。

如果失败不是选项,也可以将其配置为引入非编译时函数。

代码语言:javascript
复制
#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)

请注意,扩展过大,即使它会提前终止,因为编译器必须在计算之前完全插入所有内容。

票数 2
EN

Stack Overflow用户

发布于 2008-09-16 22:04:14

我意识到您对C实现只感兴趣,但我想无论如何我还是会对C++和模板元编程进行评论。我并不完全相信在C++中它是可能的,因为您需要定义好的初始条件才能终止递归扩展。

代码语言:javascript
复制
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肯定是不可能的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/76334

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档