簡體   English   中英

在編譯時計算小整數的階乘

[英]Computing the factorial of a small integer at compile time

我剛剛(再次)實現了一個遞歸模板,用於在編譯時計算整數的階乘(誰曾想過有一天我真的需要它!)。 盡管如此,我還是去找Boost尋找答案,而不是自己動手。 但是,特殊數學中的階乘函數特別禁止它使用整數類型,所以我只寫了自己的。

仍然,我應該使用Boost中的另一個功能嗎? 我應該將我的整數轉換為double並使用boost::factorial函數嗎? 計算是在編譯時執行的嗎?

你不需要Boost,如果你有C ++ 11,這只是1-liner:

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

即使你的arg也不是編譯時間常量,它也會工作。 uint64_t適用於n <21。

如果您在編譯時執行此操作並乘以浮點值 - 則不會產生轉換開銷(轉換也將在編譯時進行)。

由於可以在整數內部使用有限數量的因子,因此您可以手動預先計算前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初始化了fourFactorial

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

與使用遞歸編譯時技巧相比,此方法可能導致更快的編譯。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM