在java中,假设有一个int
类型的数字,值为5,那么他在计算机中的表示为
00000000 00000000 00000000 00000101
那么负数该如何表示呢?
在计算机中,正数是直接用原码
来表示的,例如单字节5,表示为0000 0101
-5使用补码
来表示,为1111 1011
那么什么是补码
呢?我们需要从原码和反码开始说起。
什么是原码?
一个正数的原码,是按照绝对值大小转换成的二进制数;
一个负数的原码,是按照绝对值大小转换成的二进制数,并且最高为位补1;
例如:
00000000 00000000 00000000 00000101是 5 的原码。
10000000 00000000 00000000 00000101是 -5 的原码。
什么是反码?
正数的反码与原码相同,负数的反码为除该数的符号位以外各位取反。
例如:
00000000 00000000 00000000 00000101是 5 的反码。
11111111 11111111 11111111 11111010是 -5 的反码。
什么是补码?
正数的补码与原码相同,负数的补码为反码最后一位加1.
例如:
00000000 00000000 00000000 00000101是 5 的补码。
11111111 11111111 11111111 11111011是 -5 的补码。
一个栗子
在计算机中,负数以原码的补码形式表达。现在我们手动计算单字节 -1 的补码:
第一步,计算原码:
1000 0001
第二步,计算反码(除最高位以外取反):
1111 1110
第三步,反码低位补1得到补码:
1111 1111
另一个栗子
判断下面的等式是否成立:
-x=!x+1
x正数的情况:
0000 0101 数字 5 原码
1111 1011 取反得到反码 + 1
1111 1011 数字 -5
x负数的情况:
1111 1011 数字 -5 补码形式
0000 0101 取反得到反码 + 1
0000 0101 数字 5 原码
结论:
正数转负数:正数二进制表示按位取反,并且在低位补1;
0000 0101 ==> 1111 1011
负数转正数:负数二进制表示按位取反,并且在低位补1;
1111 1011 ==> 0000 0100 ==> 0000 0101
>>> 与 >>
明白了二进制负数与正数的表示形式后,无符号右移与有符号右移就比较好理解了:
>>:按照二进制把数字右移指定数位,符号位为正补零,符号位负补一,低位直接移除。
>>>:按照二进制把数字右移指定数位,高位直接补零,低位移除。