1
1
首先列出从1向上的结果,
接下来,当
那么,当
继续,你可以看到
通过诱导。 你可以重写为
从数学上讲,你也可以
不过,如果使用固定宽度类型,最后一个公式可能会溢出。 所以问题是
对于固定宽度的类型,即有界范围,所有这些当然都是O(1)运算,但你可能仍然有兴趣使其尽可能高效,即使计算复杂性并没有进入游戏。
对于本机类型-
许多处理器都有一条机器指令来计算机器类型值中的前导0位,如果编译器可以访问该指令,则可以非常快速地实现以2为底的对数。如果没有,您可以使用获得比递归更快的版本 one of the classic bit-hacks .
例如,足够新的gcc和clang版本具有
版本
使用
需要0.626秒,而天真的循环
耗时1.865秒。
如果不使用固定宽度的类型,而是使用任意精度的整数,情况会有所改变。naive循环(或递归)仍然使用
|
2
1
如果你认为算法是迭代的,数字是二进制的,那么这个函数会移出最低位,如果移出的是1,则会将数字增加1。因此,除了增量之外,它对数字中的位数(即最高的1的位置)进行计数。增量最终会使结果增加一,除非数字的形式是1000……因此,您可以得到位数加一,或者如果数字是二的幂,则可以得到位数。根据您的机器型号,这可能比O(logn)计算得更快。 |
James · 阻塞问题的一种算法设计[C++代码] 7 年前 |
qwark · C++中非常快速的近似对数(自然对数)函数? 8 年前 |
user2946696 · 没有java.lang.Math的二进制对数? 10 年前 |
R_User · 如何将线性回归绘制为双对数R图? 11 年前 |