【发布时间】:2014-05-21 11:09:56
【问题描述】:
编辑:在最初的问题中有一个错误的公式,并且尝试的算法正在做一些与预期完全不同的事情。很抱歉,我决定重写问题以消除所有混乱。
我需要在编译时计算(结果将用作非类型模板参数)存储n不同状态所需的最小位数:
constexpr unsigned bitsNeeded(unsigned n);
或通过模板
结果应该是:
+-----------+--------+
| number of | bits |
| states | needed |
+-----------+--------+
| 0 | 0 | * or not defined
| | |
| 1 | 0 |
| | |
| 2 | 1 |
| | |
| 3 | 2 |
| 4 | 2 |
| | |
| 5 | 3 |
| 6 | 3 |
| 7 | 3 |
| 8 | 3 |
| | |
| 9 | 4 |
| 10 | 4 |
| .. | .. |
| 16 | 4 |
| | |
| 17 | 5 |
| 18 | 5 |
| .. | .. |
+-----------+--------+
供参考的初始(以某种方式更正)版本:
我需要计算在编译时(结果将用作非类型模板参数)存储n不同状态所需的最小位数,即积分部分(向下取整) 二进制对数向上取整:
constexpr unsigned ceilLog2(unsigned n);
这是我想出的(完全错误):
constexpr unsigned intLog2(unsigned num_states_) {
return
num_states_ == 1 ?
1 :
(
intLog2(num_states_ - 1) * intLog2(num_states_ - 1) == num_states_ - 1 ?
intLog2(num_states_ - 1) + 1 :
intLog2(num_states_ - 1)
);
}
这会产生正确的结果(对于 num_states_ != 0),但递归会呈指数级增长,并且对于任何大于 10 的输入(内存使用量)实际上无法使用在编译过程中超过 2GB,操作系统冻结并且编译器崩溃)。
如何在编译时以实用的方式计算它?
【问题讨论】:
-
我不敢相信这会产生正确的结果。
-
@Henrik 没有。
intLog2Runtime(256) = 16,intLog2Runtime(1024) = 32. -
@DanielKO GCC 4.8 complains for 1024...
-
您似乎在尝试计算平方根,而不是对数。
-
最小位数是向上取整(而不是向下)的二进制对数。
标签: c++ c++11 compile-time constexpr logarithm