负数的二进制存储
在计算机中采用二进制存数
为了方便区分正负数,使用最高位作为符号位,最高位为 0 代表正数,最高位为 1 代表负数
例如
00000000 00000000 00000000 00000110 表示 6
10000000 00000000 00000000 00000110 表示 -6
但是在计算机中,正数直接转成原码进行存储,针对负数,则需要转成补码进行存储。
补码的计算
补码 = 原码取反+1
注意:符号位不参与取反
例如 -1的二进制表示为
原码:10000000 00000000 00000000 00000001
反码:11111111 11111111 11111111 11111110
补码:11111111 11111111 11111111 11111111
那正负数存储存在差别,对于 ~(非)操作怎么执行呢?
情况一:正数执行非操作
System.out.println(~(0b11011)); // ~27 = -28
27 为正数符号位为0, 但是取非操作符号位也要取反,导致数的正负性改变了!因此要改变存储方式。这里即原码变补码
27:00000000 00000000 00000000 00011011
~27:11111111 11111111 11111111 11100100
变补码
取反:10000000 00000000 00000000 00011011
+1:10000000 00000000 00000000 00011100
结果为 -28
情况二:负数执行非操作
System.out.println(~(0b10000000000000000000000000011100)); // ~(-28) = 2147483619
-28 为负数按照补码形式存储,取非以后符号位改变变为正数,不需要再取补码,因此全部取反之后就是最后结果
-28:10000000 00000000 00000000 00011100
~(-28):01111111 11111111 11111111 11100011
结果为 2147483619 = 2147483647 - 28
总结:
1、正数最高位为0,直接按照原码形式存储;负数最高位为1,按照二进制的补码形式存储。
2、正数 x 执行 ~ 操作 结果为 -(x+1)。
3、负数 x 执行 ~ 操作 结果为 该类型数最大正数 + x。例如 对于整型 x,~x = 2^31-1 + x