Java 按位最高有效集位

Java 按位最高有效集位,java,bit-manipulation,Java,Bit Manipulation,我想找到设置为1的最高有效位。我尝试了所有可能的方法,从&到将1到31的所有位进行ORing,但都不起作用 就像如果1000000我想要7 您想要的是像32-Integer.numberofleadingzero(value)这样的东西,也许不是最有效的,但这应该可以: public int firstBit(int i) { return i < 0 ? 31 : i == 0 ? 0 : Integer.toString(i, 2).length(); } public in

我想找到设置为
1
的最高有效位。我尝试了所有可能的方法,从
&
到将
1
31
的所有位进行ORing,但都不起作用

就像如果
1000000
我想要
7


您想要的是像
32-Integer.numberofleadingzero(value)
这样的东西,也许不是最有效的,但这应该可以:

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

只是为了添加另一种方法

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;
}
public static int mostSignificantBit(int b){
对于(inti=10;i/=2,j++){
如果((b&i)>0){
返回31-j;
}
}
返回-1;
}

如果您坚持直接使用位运算符,可以尝试以下方法:

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;
}
private int mostSignificantBit(int myInt){
int mask=1=0;bitIndex--){
如果((myInt和mask)!=0){
返回bitIndex;
}
掩码>>>=1;
}
返回-1;
}

我们将掩码初始化为
1逐次逼近将使迭代最小化为五个循环:

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;
}
unsigned int mostSignificantBit(uint32\u t val){
无符号整数位=0;
/*4=对数(val)*8)/对数(2)-1*/
对于(int r=4;r>=0;--r){
无符号移位=1>移位;
if(sval){
位+=移位;
val=sval;
}
}
返回位;
}

虽然有一个答案是可以接受的,但我有另一种分享的方式,我认为这更容易

如果您想使用位运算,下面是一种方法。基本上,我将整数右移,直到它变为零。不需要面具

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;
}
private static int mostSignificantBit(int myInt){
if(myInt==0)返回0;//0的特殊处理
if(myInt<0)返回32;//对-ve的特殊处理
return(int)(Math.log(myInt)/Math.log(2))+1;
}

我遇到过的最精巧的实现——三次迭代和一次查表

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];
}

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

对于小端格式:

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

你详细尝试了什么?结果是什么?我做了所有的计数+=1&(~x>>1-31);它给了我不同于我预期的数字,我想要最高有效位是1,这就是负数应该如何处理?没关系,我需要最高有效位是1,仅此而已。因此,即使我有-2,我仍然需要1的最高有效位,返回8到31时发生了什么?您可能希望输入
int
,而不是
字节
。我认为您的起点不正确。这段代码给出了与负数相同的
Integer.MAX_VALUE
答案。实际上,使用无符号右移运算符很重要。如果
myInt
不是负数,则需要移位
mask
,它以负值开始。如果使用带符号的右移,则
mask
将始终有一个不属于的前导1,这是正确的(因为
mask
以负数开始)。然而,这并不影响我的实现结果,因为当
myInt
不是负数时,多余的1位总是
ed为0(即
myInt
的符号位,我们刚才说的是正数)。这一点很好!我还没有研究过在
掩码
中引入1的后果,正如你所指出的那样,这完全是无稽之谈。不。。。只是不。是的,它是有效的,但哎哟,它是浪费。
((yourByte & yourBitMask) >> msbIndex) && 0x01