计算小整数在编译时的阶乘(Computing the factorial of a small in

2019-09-20 13:23发布

我只是执行(再次)在编译时计算整数的阶乘递归模板(谁曾想过有一天我会真的需要它!)。 尽管如此,而不是我自己的滚动,我去升压寻找一个答案。 然而,在特殊的数学阶乘函数明确禁止它的使用与整型,所以我只是写我自己。

不过,有没有帮助其他的功能,我应该使用? 我要抛弃我的整数double ,并使用boost::factorial功能? 被计算在编译时进行的?

Answer 1:

你不需要加速,这仅仅是1班轮,如果你有C ++ 11:

constexpr uint64_t factorial(uint64_t n) { 
    return n == 0 ? 1  :  n * factorial(n-1); 
}

它会工作,即使你的arg是不编译时间常数也。 uint64_t中将具有n <21工作。

如果在编译的时候做这件事,并与浮点值乘 - 将没有转换的开销(转换将在编译的时候也是如此)。



Answer 2:

由于有可以容纳一个整数内部阶乘的有限数量的,可以简单地用手预先计算第一20个值,并将它们存储在全局或静态阵列。 然后使用一个全局或静态函数查找数组中的阶乘:

#include <iostream>

const int factorials[] =
{
    1,
    1,
    2,
    6,
    24,
    // etc...
};

inline const int factorial(int n) {return factorials[n];}

int main()
{
    static const int fourFactorial = factorial(4);
    std::cout << "4! = " << fourFactorial << "\n";
}

如果您使用文字作为参数传递给factorial ,那么编译器应该简单地与结果替代函数调用(在启用优化之后)。 我试图在XCode中4.4(在Mac)上面的例子中,我在于其初始化组件看到fourFactorial与恒定24:

.loc    1 20 38  ## /Users/emile/Dev/sandbox/sandbox/main.cpp:20:38
movl    $24, __ZZ4mainE13fourFactorial(%rip)

这种方法可能会导致编译速度比使用递归编译时的技巧。



文章来源: Computing the factorial of a small integer at compile time