按位最重要的设置位

时间:2012-02-02 18:24:42

标签: java bit-manipulation

我想找到设置为1的最重要位。我已经尝试了从&到OR 131的所有位的所有可能方式,但它不起作用。

如果1000000我希望7

10 个答案:

答案 0 :(得分:17)

http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Integer.html#numberOfLeadingZeros%28int%29 你想要32 - Integer.numberOfLeadingZeros(value)

之类的东西

答案 1 :(得分:7)

虽然接受了答案,但我还有其他方式可以分享,我认为这样更容易。

如果你想使用按位运算,这就是方法。基本上,我正在移动整数,直到它变为零。不需要面罩。

private static int mostSignificantBit(int myInt){
    int i = 0;
    while (myInt != 0) {
        ++i;
        myInt >>>= 1;
    }
    return i;
}

另一种方法是以数学方式计算:

private static int mostSignificantBit(int myInt){
    if (myInt == 0) return 0;    // special handling for 0
    if (myInt < 0) return 32;    // special handling for -ve

    return (int)(Math.log(myInt)/Math.log(2)) +1;
}

答案 2 :(得分:6)

我遇到的最简单的实现 - 三次迭代和一次表查找。

unsigned int msb32(unsigned int x)
{
    static const unsigned int bval[] =
    { 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4 };

    unsigned int base = 0;
    if (x & 0xFFFF0000) { base += 32/2; x >>= 32/2; }
    if (x & 0x0000FF00) { base += 32/4; x >>= 32/4; }
    if (x & 0x000000F0) { base += 32/8; x >>= 32/8; }
    return base + bval[x];
}

答案 3 :(得分:3)

如果你坚持直接使用按位运算符,你可以尝试这样的事情:

private int mostSignificantBit(int myInt){
  int mask = 1 << 31;
  for(int bitIndex = 31; bitIndex >= 0; bitIndex--){
    if((myInt & mask) != 0){
      return bitIndex;
    }
    mask >>>= 1;
  }
  return -1;
}

我们将掩码初始化为1 << 31,因为它代表1后跟31 0。我们使用该值来测试索引31(第32个点)是否为1.当我们and此值与myInt时,我们得到0,除非在myInt中设置了相应的位。如果是这种情况,我们会返回bitIndex。如果没有,那么我们将掩码向右移动1并再试一次。我们重复,直到我们用完要移位的地方,在这种情况下,它意味着没有设置任何位(可能你想在这里抛出异常而不是返回-1)。

请注意,这将为01返回6的值64(二进制为1000000)。如果您愿意,可以调整。另请注意,我使用了无符号右运算符而不是带符号的右移位运算符。这是因为这里的意图是处理原始位而不是它们的带符号解释,但在这种情况下并不重要,因为所有负值将在转换发生之前在循环的第一次迭代中终止。

答案 4 :(得分:2)

逐次逼近将最小化到五个循环的迭代:

unsigned int mostSignificantBit(uint32_t val) {
  unsigned int bit = 0;

  /* 4 = log(sizeof(val) * 8) / log(2) - 1 */
  for(int r = 4; r >= 0 ; --r) {
    unsigned shift = 1 << r; /* 2^r */
    uint32_t sval = val >> shift;
    if (sval) {
        bit += shift;
        val = sval;
    }
  }
  return bit;
}

答案 5 :(得分:0)

也许不是最有效的,但这应该有效::

public int firstBit(int i) {
    return i < 0 ? 31 : i == 0 ? 0 : Integer.toString(i, 2).length();
}

答案 6 :(得分:0)

只需使用Long或Integer类的numberOfTrailingZeros(value)方法。

答案 7 :(得分:0)

对于Little Endian格式:

((yourByte & yourBitMask) >> msbIndex) && 0x01

答案 8 :(得分:-1)

只是添加另一种方法

public static int mostSignificantBit(int b) {
    for (int i = 1 << 30, j = 0; i > 0; i /= 2, j++) {
           if ((b & i) > 0) {
            return 31-j;
        }
    }
    return -1;
}

答案 9 :(得分:-3)

if( value | 0x40 ) return 7;
else if( value | 0x20 ) return 6;
else if( value | 0x10 ) return 5;
else if( value | 0x8 ) return 4;
else if( value | 0x4 ) return 3;
else if( value | 0x2 ) return 2;
else if( value | 0x1 ) return 1;