C中的比特:如何从2 ^ N转换为N?

时间:2010-11-13 18:21:58

标签: c bit-manipulation

将[2 ^ N,2 ^(N-1)-1]范围内的数字转换为N?

是一个很好的比特例程

一些例子:

  • f(1) - > 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);
}

3 个答案:

答案 0 :(得分:4)

根据您的数据类型的宽度以及可用内存的大小,查找表是一种可能性。这几乎肯定是最快的方法。

有关其他方法,请参阅http://www-graphics.stanford.edu/~seander/bithacks.html#IntegerLogObvious以及后续部分。

答案 1 :(得分:3)

作为最常用的方法,二分查找可能有所帮助。对于值0..31,它只需要5个阶段。

y = 0;
if(x >= 0x10000<<y) y += 0x10;
if(x >= 0x100<<y) y += 0x08;
if(x >= 0x10<<y) y += 0x04;
if(x >= 0x4<<y) y += 0x02;
if(x >= 0x2<<y) y += 0x01;

答案 2 :(得分:1)

在此页面上查看黑客的计算基数2对数(或前导零数,它们是相同的):http://www-graphics.stanford.edu/~seander/bithacks.html

您还可以为x86找到有用的函数__builtin_clz(或VS的_BitScanReverse)。