来源:http://hi.baidu.com/bgpxjhfhoidgpre/item/1c5cbe3046f4b7f2e6bb7a62
运算规则
计算机中的数字运算是以补码形式进行的。所以在做位运算时,首先要将数字转换为补码形式。
补码规则
正数的原码、反码、补码都相同。
负数的反码是除符合位为1外,其他位全取反,简单地说,负数求补码,“反码加1“。
这句话是不负责任的,因为原码、反码和补码概念中,存在符号位,总结一下,”取反加1“时符号位怎么办:
1)取反时,符号位不参与取反。
2)加1时,符号位参与加1。
3)特殊补码,即首位为1,其它位全是0。对于这种形式的补码,不要去求它的原码了,求出来也不对,它就表示该类型中的最小负数,比如10000000表示byte类型中的最小负数-128。
已知一个数的补码,求原码的操作分两种情况:
(1)如果补码的符号位为“0”,表示是一个正数,所以补码就是该数的原码.
(2)如果补码的符号位为“1”,表示是一个负数,求原码的操作可以是:符号位为1,其余各位取 反,然后再整个数加1.
例如,已知一个补码为11111001,则原码是10000111(-7):因为符号位为“1”,表示是一个负数,所以该位不变,仍为“1”;其余7位1111001取反后为0000110;再加1,所以是10000111.
java位运算规则
java有7种位运算符:与(&),或(|),异或(^),取反(~),左移(<<),有符号右移(>>),无符号右移(>>>)。
这7种位运算符,运算时,符号位都要参与运算。
有了上面3种规则,java位运算就很简单了,
例子1:与(&)
int a=127;
int b=-2;
int c=a&b;
System.out.println(c);
打出来的是
126
运算过程:
先求补码,
127的补码是
00000000 00000000 00000000 01111111,
-2的补码是
11111111 11111111 11111111 11111110
所以a&b的结果是
00000000 00000000 00000000 01111110
这个数仍旧是补码,要求它的原码,很简单,它是正数,原码就是本身,即126。
例子2:取反(~)
int a=Integer.MAX_VALUE;
int b=~a;
System.out.println(b);
打出来的是
-2147483648
运算过程:
a是int中最大的正数,所以a的补码是
01111111 11111111 11111111 11111111
取反后的补码是
10000000 00000000 00000000 00000000
这是个特殊补码,即int中最小的负数,-2147483648。
System.out.println(Integer.MIN_VALUE);
System.out.println(Integer.MAX_VALUE);
打印看看
-2147483648
2147483647
例子3:左移(<<)
int a=1;
int b=a<<31;
System.out.println(b);
打印出来的是
-2147483648
运算过程:
1的补码是
00000000 00000000 00000000 00000001
左移31位后
10000000 00000000 00000000 00000000
这个很眼熟了吧,int中最小的负数,所以是-2147483648。