因此,例如0110有1位和2位,1000有3位,1111有0,1,2,3位
答案 0 :(得分:7)
如果实际上只有4位,那么最快的方法肯定会涉及查找表。毕竟只有16种不同的可能性。
答案 1 :(得分:6)
互联网上所有位黑客的最佳参考资料 - bit twiddling hacks
答案 2 :(得分:4)
我会将其向下移动并测试循环中最不重要的位。使用32位掩码(或无符号整数的长度)可能会更快进行测试。
/阿伦
答案 3 :(得分:4)
for( int i = 0; variable ; ++i, variable >>= 1 ) {
if( variable & 1 )
// store bit index - i
}
答案 4 :(得分:1)
如果是.NET,你必须经常使用它,我想要一个漂亮的流畅界面。
我会创建以下类(对BitTools这个名称并不完全满意)。
[Flags]
public enum Int32Bits
{
// Lookup table but nicer
None = 0,
Bit1 = 1, Bit2 = 1 << 1, Bit3 = 1 << 2, Bit4 = 1 << 3, Bit5 = 1 << 4, Bit6 = 1 << 5, Bit7 = 1 << 6, Bit8 = 1 << 7,
Bit9 = 1 << 8, Bit10 = 1 << 9, Bit11 = 1 << 10, Bit12 = 1 << 11, Bit13 = 1 << 12, Bit14 = 1 << 13, Bit15 = 1 << 14, Bit16 = 1 << 15,
Bit17 = 1 << 16, Bit18 = 1 << 17, Bit19 = 1 << 18, Bit20 = 1 << 19, Bit21 = 1 << 20, Bit22 = 1 << 21, Bit23 = 1 << 22, Bit24 = 1 << 23,
Bit25 = 1 << 24, Bit26 = 1 << 25, Bit27 = 1 << 26, Bit28 = 1 << 27, Bit29 = 1 << 28, Bit30 = 1 << 29, Bit31 = 1 << 30, Bit32 = 1 << 31,
}
public static class BitTools
{
public static Boolean IsSet(Int32 value, Int32Bits bitToCheck)
{
return ((Int32Bits)value & bitToCheck) == bitToCheck;
}
public static Boolean IsSet(UInt32 value, Int32Bits bitToCheck)
{
return ((Int32Bits)value & bitToCheck) == bitToCheck;
}
public static Boolean IsBitSet(this Int32 value, Int32Bits bitToCheck)
{
return ((Int32Bits)value & bitToCheck) == bitToCheck;
}
public static Boolean IsBitSet(this UInt32 value, Int32Bits bitToCheck)
{
return ((Int32Bits)value & bitToCheck) == bitToCheck;
}
}
您可以通过以下方式使用它:
static void Main(string[] args)
{
UInt32 testValue = 5557; //1010110110101;
if (BitTools.IsSet(testValue, Int32Bits.Bit1))
{
Console.WriteLine("The first bit is set!");
}
if (testValue.IsBitSet(Int32Bits.Bit5))
{
Console.WriteLine("The fifth bit is set!");
}
if (!testValue.IsBitSet(Int32Bits.Bit2))
{
Console.WriteLine("The second bit is NOT set!");
}
}
对于每个(U)Int大小,您可以创建另一个Int * Bits枚举以及IsSet和IsBitSet的正确重载。
编辑:我误读了,你说的是无符号的整数,但在这种情况下它是一样的。答案 5 :(得分:0)
答案 6 :(得分:0)
@Allan Wind ......
不需要额外的位移。不进行位移更有效,因为比较最低有效位与比较第二最低有效位同样有效,依此类推。进行一点移位只是将所需的位操作加倍。
firstbit = (x & 0x00000001)
secondbit = (x & 0x00000002)
thirdbit = (x & 0x00000004) //<-- I'm not saying to store these values, just giving an example.
...
无论如何,x86系统上的所有操作都是使用32位寄存器完成的,因此单个位比较与32位比较一样有效。
更不用说拥有循环本身的开销。
问题可以在恒定数量的代码行中完成,代码是在x86还是x64上运行,我所描述的方式更有效。
答案 7 :(得分:0)
您可以采用迭代遍历int的字节的混合方法,使用查找表来确定每个字节中的设置位的索引(分解为半字节)。然后,您需要向索引添加偏移量以反映其在整数中的位置。
即。假设您从32位int的MSB开始。高位半字节索引我将调用upper_idxs,低位半字节索引我将调用lower_idxs。然后你需要为lower_idxs的每个元素添加24,并为upper_idxs的每个元素添加28。下一个字节将被类似地处理,除了偏移量分别为16和20,因为该字节是8位“向下”。
对我而言,这种方法似乎是合理的,但我很乐意证明是错误的: - )
答案 8 :(得分:0)
两个步骤:
使用set_bit= x & -x; x&= x - 1;
减去1并计算位数。
答案 9 :(得分:0)
我认为这会有所帮助
import java.util.*;
public class bitSet {
public static void main(String[]args) {
Scanner scnr = new Scanner(System.in);
int x = scnr.nextInt();
int i = 0;
while (i<32) {
if ( ((x>>i)&1) == 1) {
System.out.println(i);
}
i++;
}
}
}