原码、反码、补码
1. 原码、反码、补码
以int a = 128 和 int b = -128为例。int在jvm内存中占用四字节,总共32位,最高位是正、负号标识符
正数:int a = 128
原码:
0000 0000 0000 0000 0000 0000 1000 0000
反码:
0000 0000 0000 0000 0000 0000 1000 0000
补码:
0000 0000 0000 0000 0000 0000 1000 0000
从这里可以看出,正数的原码、反码、补码是一样的。
负数:int b = -128
原码:
1000 0000 0000 0000 0000 0000 1000 0000
反码:
1111 1111 1111 1111 1111 1111 0111 1111
原码除最高位标识符以外,其余位取反就是反码
补码:
1111 1111 1111 1111 1111 1111 1000 0000
反码 最低为加1 得到的就是补码
在操作系统内存中,不管正数还是负数存的都是补码。而参与运算的也都是补码。
2. 异或运算
java的异或运算符为:^,以下面例子为例,我们来分析异或是怎么运算的
int result = 1 ^ -1;
1的补码为:
0000 0000 0000 0000 0000 0000 0000 0001
-1的补码为:
1111 1111 1111 1111 1111 1111 1111 1111
异或运算,相同位数值相同为0,不同则为1,最高位也参与运算。按这个逻辑操作,得到新的补码:
1111 1111 1111 1111 1111 1111 1111 1110
最高位是1,是个负数,转换为反码最低位-1,得到反码:
1111 1111 1111 1111 1111 1111 1111 1101
最高位是1,是个负数,转换为原码除最高位以为取反,得到原码:
1000 0000 0000 0000 0000 0000 0000 0010:
这个结果是:-2;
3. 位移运算
java的位移运算符有:
<< :左移运算符,不移动符合
>> : 右移运算符,不移动符号
>>> : 无符号右移,移动符号
以下面例子为例,我们来分析位移运算是怎么运算的
正数 >>:
int a = 4 >> 2
4的补码是:
0000 0000 0000 0000 0000 0000 0000 0100
最高位标识符不变,其他位整体向右移动2位,空缺高位 按0 补充,得到新的补码:
0000 0000 0000 0000 0000 0000 0000 0001
转换为原码:
0000 0000 0000 0000 0000 0000 0000 0001
结果是1。
正数 <<:
int a = 4 << 2
4的补码是:
0000 0000 0000 0000 0000 0000 0000 0100
最高位标识符不变,其他位整体向左移动2位,空缺底位 按0 补充,得到新的补码:
0000 0000 0000 0000 0000 0000 0001 0000
转换为原码:
0000 0000 0000 0000 0000 0000 0001 0000
结果是16。
正数 >>>:
int a = 4 >>> 2
4的补码是:
0000 0000 0000 0000 0000 0000 0000 0100
整体向右移动2位,空缺位 按0 补充,得到新的补码:
0000 0000 0000 0000 0000 0000 0000 0001
转换为原码:
0000 0000 0000 0000 0000 0000 0000 0001
结果是1。
负数 >>:
int a = -4 >> 2
-4的补码是:
1111 1111 1111 1111 1111 1111 1111 1100
最高位标识符不变,其他位整体向右移动2位,空缺高位 按1 补充,得到新的补码:
1111 1111 1111 1111 1111 1111 1111 1111
转换为原码:
1000 0000 0000 0000 0000 0000 0000 0001
结果是-1。
负数 <<:
int a = -4 << 2
-4的补码是:
1111 1111 1111 1111 1111 1111 1111 1100
最高位标识符不变,其他位整体向左移动2位,空缺低位 按0 补充,得到新的补码:
1111 1111 1111 1111 1111 1111 1111 0000
转换为原码:
1000 0000 0000 0000 0000 0000 0001 0000
结果是-16。
负数 >>>:
int a = -4 >>> 2
-4的补码是:
1111 1111 1111 1111 1111 1111 1111 1100
整体向右移动2位,空缺位 按0 补充,得到新的补码:
0011 1111 1111 1111 1111 1111 1111 1111
转换为原码:
0011 1111 1111 1111 1111 1111 1111 1111
结果是1073741823。