按位最重要的设置位
我想找到设置为1
的最重要位。 我已经尝试了从&
到ORing从1
到31
所有位的所有可能的方式,它不起作用。
就像1000000
我想拥有7
。
如果你坚持直接使用按位运算符,你可以尝试这样的事情:
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
此值时,除非在myInt
设置相应的位,否则我们得到0。 如果是这种情况,我们返回bitIndex
。 如果没有,那么我们将掩码向右移动1并再试一次。 我们重复,直到我们用完要移位的地方,在这种情况下,它意味着没有设置任何位(可能你想在这里抛出exception而不是返回-1)。
请注意,这将返回值0
为1
和6
为64
(二进制为1000000
)。 如果您愿意,可以调整它。 另请注意,我使用了无符号右运算符而不是带符号的右移位运算符。 这是因为这里的意图是处理原始位而不是它们的带符号解释,但是在这种情况下无关紧要,因为所有负值将在转换发生之前在循环的第一次迭代中终止。
http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Integer.html#numberOfLeadingZeros%28int%29你想要32 - Integer.numberOfLeadingZeros(value)
。
虽然有一个答案被接受,但我有另一种方式可以分享我认为更容易的方法。
如果你想使用按位运算,这就是方法。 基本上,我正在移动整数,直到它变为零。 不需要面罩。
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; }
我遇到过最简单的实现 – 三次迭代和一次表查找。
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]; }
逐次逼近将最小化到五个循环的迭代:
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; }
也许不是最有效的,但这应该有效::
public int firstBit(int i) { return i < 0 ? 31 : i == 0 ? 0 : Integer.toString(i, 2).length(); }
只需使用Long或Integer类的numberOfTrailingZeros(value)方法即可。
对于Little Endian格式:
((yourByte & yourBitMask) >> msbIndex) && 0x01
只是添加另一种方法
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; }
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;
- 使用AXIS2将用户/密码添加到SOAPHeader以进行WebService客户端调用
- 使用Java在HTML中转换XML + XSL
- imageio.IIOException:无法读取输入文件
- Itext阿拉伯字体作为问号
- JAXB – Java / XMLValue和XMLElement冲突
- h:commandbutton,如何重定向到外部站点?(JSF 2)
- 在这个例子中无法理解递归是如何工作的
- 如何使用hibernate JPA注释映射嵌套集合Map <Key,List >?
- 为什么我用Apache Commons FileUpload获得“FileUploadException:Stream意外结束”?