是否有一种简单的方法可以只使用位运算从2的幂中提取指数?
编辑:尽管这个问题最初是关于按位操作的,但是如果您想知道“在python中找到x的最快方法是什么,而y=2x?”,那么这个线程也是一个很好的读物。**
我目前正在尝试优化一个程序(Rabin-Miller primality test),它可以减少形式中的偶数n。我可以通过以下方式获得2**s * d
部分:
two_power_s = N & -N
但是我找不到一种方法来用逐位运算提取“s”。我目前正在测试的解决方法没有太多的满足感(它们都很慢),它们是:
使用对数函数
操作2*s的二进制表示(即计算尾随零)
循环除以2直到结果为1
我正在使用python,但我想这个问题的答案应该是语言不可知论。
最佳答案
“语言不可知论”和对性能的担忧几乎是不相容的概念。
大多数现代处理器都有CLZ指令,“计数前导零”。在gcc中,你可以使用内置的clz(x)(如果不是最快的话,它也可以为缺少clz的目标生成合理的代码)。注意,这个CLZ是为零定义的,所以如果它在应用程序中很重要的话,您需要一个额外的分支来捕获这个案例。
在celt(http://celt-codec.org)中,我们用于缺少clz的compliers的无分支clz由Timothy B.Terriberry编写:
int ilog(uint32 _v){
int ret;
int m;
ret=!!_v;
m=!!(_v&0xFFFF0000)<<4;
_v>>=m;
ret|=m;
m=!!(_v&0xFF00)<<3;
_v>>=m;
ret|=m;
m=!!(_v&0xF0)<<2;
_v>>=m;
ret|=m;
m=!!(_v&0xC)<<1;
_v>>=m;
ret|=m;
ret+=!!(_v&0x2);
return ret;
}
(注释表明这比分支版本和基于查找表的版本更快)
但如果性能如此关键,您可能不应该在Python中实现这部分代码。