Java bithift陌生

Java有两个用于右移的位移操作符:

>> shifts right,and is dependant on the sign bit for the sign of the result

>>> shifts right and shifts a zero into leftmost bits

http://java.sun.com/docs/books/tutorial/java/nutsandbolts/op3.html

这看起来相当简单,所以任何人都可以向我解释为什么这个代码,当bar为-128的值时,为foo产生-2的值:

byte foo = (byte)((bar & ((byte)-64)) >>> 6);

这意味着要做一个8位字节,最左边2位的掩码,并将它们移到最右边的2位.即:

initial = 0b10000000 (-128)
-64 = 0b11000000
initial & -64 = 0b10000000
0b10000000 >>> 6 = 0b00000010

结果实际上是-2,即

0b11111110

IE浏览器. 1s而不是零被移动到左侧位置

最佳答案
这是因为&实际上是对int执行升级 – 这留下了大量的“1”位.然后你向右移动,将最左边的2位保留为0,然后通过转回字节忽略那些最左边的位.

当你将操作分开时,这会变得更清晰:

public class Test
{
    public static void main(String[] args)
    {
        byte bar = -128;
        int tmp = (bar & ((byte)-64)) >>> 6;
        byte foo = (byte)tmp;
        System.out.println(tmp);
        System.out.println(foo);
    }
}

版画

67108862
-2

所以再做一点算术:

initial = 0b10000000 (-128)
-64 = 0b11000000
initial & -64 = 0b11111111111111111111111110000000 // it's an int Now
0b10000000 >>> 6 = 0b00111111111111111111111111100000 // note zero-padding
(byte) (0b10000000 >>> 6) = 11100000 // -2

即使你从&操作(通过那时的铸造),>>>无论如何,将首先将第一个操作数提升为int.

编辑:解决方案是改变你掩盖事物的方式.而不是通过-64屏蔽,而是仅通过128 64 = 192 = 0xc0掩码:

byte foo = (byte)((bar & 0xc0) >>> 6);

这样你真的只剩下你想要的两个位,而不是在最重要的24位中加载1.

相关文章

最近看了一下学习资料,感觉进制转换其实还是挺有意思的,尤...
/*HashSet 基本操作 * --set:元素是无序的,存入和取出顺序不...
/*list 基本操作 * * List a=new List(); * 增 * a.add(inde...
/* * 内部类 * */ 1 class OutClass{ 2 //定义外部类的成员变...
集合的操作Iterator、Collection、Set和HashSet关系Iterator...
接口中常量的修饰关键字:public,static,final(常量)函数...