关于补码,有如下比较有趣的演化过程:
假如计算机中使用 4 位的二进制表示数据,如图-2,最多能表示 0 到 15(10 进制),之后有牛人做了 一个细微改动,如图-3,将所有二进制以 1 开头的数(大于 7 的数)放到 0 之前,并且规定用来表示负 数-1 到-8,这就是 4 位补码: 如图-4
仔细观察会发现,如图-5,-1(1111)+1(0001) = 0(1 0000),如果溢出最高位"1"保留 4 个"0" (因为仅 4 位运算),那么得到-1+1=0,同理-8(1000)+7(0111)=-1(1111)。
至此,得出了结论:在封闭的四位运算中(超出 4 位就丢弃),这种设计和规定是非常合理的。
可是,我们又有了疑问:
(-1)*(-1) = ?
会不会和结果就不一样了?
如图-6,结果一样。(-1)*(-1) = 1
即 1111 * 1111 = 0001
。这种数据运算规则就是补码运算。
知识点:
- 计算机中二进制的正数和负数的关系是取反加一。举例如:
~3+1=-3(~3表示对3取反),这里是指对二进制数取反加一,只是用十进制数来表达而已,否则对3取反,怎么取,取啥?)
- 补码运算是封闭的: 运算结果保留在补码范围之内, 超范围就溢出(即舍弃掉)
- 补码边界运算有溢出风险
- 4位二进制补码最多能表示
2^4(16)
个数,数的范围是-8~7
- 8位二进制补码最多能表示
2^8(256)
个数,数的范围是-128~127
- 16位二进制补码最多能表示
2^16(65536)
个数,数的范围是-32768~32767
- 32位二进制补码最多能表示
2^32
个数,数的范围是-2G~2G-1(1G=1024*1024*1024)
如图-7,为二进制补码列表:
注意: 4 位补码不能表示 8, 要是表达 8 必须使用 8 位或以上类型的补码。