【转载】java位演算与原码反码补码

【转载】java位运算与原码反码补码

运算规则

计算机中的数字运算是以补码形式进行的。所以在做位运算时,首先要将数字转换为补码形式。

补码规则

正数就不说了,说说负数,简单地说,负数求补码,是对原码”取反加1“。
这句话是不负责任的,因为原码、反码和补码概念中,存在符号位,总结一下,”取反加1“时符号位怎么办:
1)取反时,符号位不参与取反。
2)加1时,符号位参与加1。
3)特殊补码,即首位为1,其它位全是0。对于这种形式的补码,不要去求它的原码了,求出来也不对,它就表示该类型中的最小负数,比如10000000表示byte类型中的最小负数-128。

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。