C 中的位旋转:如何从 2^N 转换为 N?
将 [2^N,2^(N-1)-1] 范围内的数字转换为 N 的良好位操作例程是什么?
一些例子:
- f(1) -> 0
- f([2-3]) -> 0 f([2-3]) -> 1
- f([4-7])→ 2
- f([8-15])→ 3
这是一种实现:
uint f(uint num)
{
for (uint shifts = 0; num; shifts++)
num >>= 1;
return (shifts - 1);
}
What is a good bit-twiddling routine to convert a number in the range [2^N,2^(N-1)-1] to N?
Some examples:
- f(1) -> 0
- f([2-3]) -> 1
- f([4-7]) -> 2
- f([8-15]) -> 3
Here is one implementation:
uint f(uint num)
{
for (uint shifts = 0; num; shifts++)
num >>= 1;
return (shifts - 1);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
作为最通用的方法,二分搜索可能会有所帮助。对于值 0..31,仅需要 5 个阶段。
As most general approach, binary search may help. For values 0..31 it need only 5 stages.
在此页面上查看计算以 2 为底的对数(或前导零计数,它们是相同的)的 hack:http://www-graphics.stanford.edu/~seander/bithacks.html
您还可以发现有用的函数
__builtin_clz
(或_BitScanReverse 对于 VS) 对于 x86。
Take a look at hacks for computing base 2 logarithm (or leading zero count, they are the same) on this page: http://www-graphics.stanford.edu/~seander/bithacks.html
You could also find useful the function
__builtin_clz
(or_BitScanReverse
for VS) for x86.根据您的数据类型的宽度以及可用内存的大小,查找表是一种可能性。这几乎肯定是最快的方法。
有关其他方法,请参阅 http://www-graphics.stanford.edu/~ seander/bithacks.html#IntegerLogObvious 以及后续部分。
Depending on how wide your data-type is, and how much memory you have available, a lookup-table is one possibility. It's almost certainly the fastest approach.
For other approaches, see http://www-graphics.stanford.edu/~seander/bithacks.html#IntegerLogObvious, and the subsequent sections.