2016-02-10 43 views
3

我有一個不同於我的圖書館的正常值,稱之爲the_val。現在,我想要log_of_the_val成爲floor(log_2(the_val)) - 不是用C++代碼說話 - 當然,我希望它在編譯時發生。現在什麼是在編譯時計算積分基2對數的正確方法?

,用gcc,我可以做類似

decltype(the_val) log_of_the_val = sizeof(the_val) * CHAR_BIT - __builtin_clz(the_val) - 1; 

,並應工作,我認爲(長 - 數標題零)。否則,我可以自己實現一個constexpr函數,但我敢打賭,還有其他更簡單,便攜的東西,我可以在編譯時使用它。 ...問題是,那會是什麼?

+0

@IlyaPopov:是的。 – einpoklum

回答

4

最直接的解決方案是使用std::log2<cmath>,但沒有指定爲constexpr - 它是在gcc下,但不是在鐺下。 (實際上,的libstdC++ std::log2調用__builtin_log2,這是constexpr下GCC)

__builtin_clz是constexpr GCC和鐺下,所以你可能要使用。

完全便攜的解決方案是寫一個遞歸constexpr整體的log 2:

constexpr unsigned cilog2(unsigned val) { return val ? 1 + cilog2(val >> 1) : -1; } 
+0

-1的基本原理是什麼?此外,我認爲,修正了1。 – einpoklum

+2

@einpoklum'log2(0)'是一個錯誤,但它簡化了返回'-1'的實現。另一種方法是終止'1'上的遞歸,併爲'0'拋出'std :: domain_error':'constexpr unsigned cilog2(unsigned val){return val> 1? 1 + cilog2(val >> 1):val == 1? 0:throw std :: domain_error {「cilog2(0)」}; }' – ecatmur

相關問題