有一些事情要记住关于Java数据类型,使这件事情的工作。
我假设你正在使用int变量,因为在表达式中没有显式强制转换。如果你为你的变量使用一个int类型:data start_pos和length;你应该使用32而不是16,因为int的值是32位的。
另外,如果你打算使用像int,short或者byte这样的整数基本类型,请记住这些基元类型是二进制补码,它们是符号扩展的,这意味着如果你对负数进行右移(评估为-1),那些将被附加在高位(符号位)而不是零上。
例如:
1111 1111 1111 1111 1111 1111 1111 1000
>>1
1111 1111 1111 1111 1111 1111 1111 1100
现在回到你的问题。一般的想法是能够做到:
data & mask
现在,生成掩码是有点棘手的签名数据类型。使用下面的方法生成掩码是有意义的:
(~0 << (32 - length) >> (32 - length - start_pos))
但是这当然不会起作用,因为符号扩展。
我会建议,而不是使用右移>>,使用旋转运算符>>>这种方式,而不是在高位上附加的方式,旋转运算符将附加低位。
例如:
1111 1111 1111 1111 1111 1111 1111 1000
>>>1
0111 1111 1111 1111 1111 1111 1111 1100
所以......
mask = (~0 << 32-length >>> 32-length-start_pos)
而你最终的答案看起来是这样的:
(data & (~0 << 32-length >>> 32-length-start_pos)) >>> start_pos
最外面的旋转操作移动您的屏蔽数据来低位。
非常感谢!在澄清我的问题和使用你的答案后,我想出了这个: return(short)((data >>>(16-p-n))&((1 << n)-1)) 这是完美的! – powerj1984 2009-06-30 16:03:34