C 如何使用位运算符计算日志基数2?
我需要用C计算一个数字的对数基数2,但我不能使用数学库。答案不需要精确,只需要精确到最接近的整数。我已经考虑过了,我知道我可以使用while循环将数字除以2,直到它小于2,并保持迭代计数,但这可以使用位运算符吗?如果使用位运算符,这很容易 你已经知道如何用2连续除法了 对于C中的任何无符号整数,C 如何使用位运算符计算日志基数2?,c,bit-manipulation,logarithm,binary-log,C,Bit Manipulation,Logarithm,Binary Log,我需要用C计算一个数字的对数基数2,但我不能使用数学库。答案不需要精确,只需要精确到最接近的整数。我已经考虑过了,我知道我可以使用while循环将数字除以2,直到它小于2,并保持迭代计数,但这可以使用位运算符吗?如果使用位运算符,这很容易 你已经知道如何用2连续除法了 对于C中的任何无符号整数,x>>1与x/2相同 如果您需要加快速度,您可以执行“分而治之”(divide-and-converge)移位,例如,每次移动4位,直到达到0,然后返回并查看最后4位。这意味着最多16个班次,19个班次,
x>>1
与x/2
相同
如果您需要加快速度,您可以执行“分而治之”(divide-and-converge)移位,例如,每次移动4位,直到达到0,然后返回并查看最后4位。这意味着最多16个班次,19个班次,而不是63个班次。在现代CPU上它是否真的更快,我不能不测试就说。你可以更进一步,先做16人一组,然后4人一组。这里可能没有什么用处,但如果您有一些1024位整数,则可能值得考虑。abamert已经回答了这个问题,但更具体地说,您将如何编写它:
Log2(x) = result
while (x >>= 1) result++;
你算是位运算符吗?如果是这样,答案很明显。如果不是,那就更棘手了。为什么你不能使用数学库?@JackManey:这大概是家庭作业,或者是自学的等价物。但那很好;他似乎已经付出了一些努力(他总是有一个可行的解决方案),并在寻找提示,看看是否有其他方法可以做到这一点,而不是让我们为他做家庭作业。你可以在下面的链接中查看-@JackManey:数学库只计算浮点数的对数,如果您的64位数字略低于2的幂但大于2^56,则
log2()
将给出错误的答案。谢谢,我不知道这有多明显。我想出来了。@SKLAK:为了增加乐趣,请尝试用-O2编译/2
和>1
代码,看看它们有什么不同。如果其中一个速度明显快于另一个,那么您很可能会得到两个完全相同的代码。它们只会在无符号的情况下相同。对于int
,有一个额外的操作来预先添加符号位,这确保结果向零而不是负无穷大舍入。@DietrichEpp:答案中已经有了,所以我认为不需要在注释中再次提及它。@SKLAK:根据快速测试,在一台带有Apple clang 4.1-O2的x86_64上,执行一步分治可以使64位数字加速2.9倍,两步加速3.3倍,但rajneesh链接中最快的方法速度要快5.8倍(假设我正确修改了64位的算法)。对于32位数字来说,这几乎没有那么引人注目。不管怎么说,如果你不需要速度,我会选择简单的版本以提高可读性,但值得阅读其他算法以获得启发。