[title]负数的概念[/title]
1 + x = 0
二进制:
0001 + x = 0000
显然,只有让结果向前进位,才会有0000这个结果。
得出,x = 1110 + 1
= 1111
即,1111是二进制的 -1
这里用到的是溢出的思想,例如:加法器硬件第5位进位不存在。
取模,同余。
同理,
0010 + y = 0000
得,y = 1101 + 1
= 1110
[title]八位二进制数下的正负数划分[/title]
同理 … …
符号 | |||||||||
1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | = | 128?(弃用) |
0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | = | 127 |
0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | = | 2 |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | = | 1 |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | = | 0 |
1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | = | −1 |
1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | = | −2 |
1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | = | −127 |
1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | = | −128?(采用) |
上表中,10000000这个值按道理既可以表示128,也可以表示-128。但我们不能让它存在二义性,只能表示一个数?
那么,谁最合适呢?
我们发现正数与负数的符号位有着明显的不同,不看10000000,正数的符号位都是0,负数的符号位都是1。所以,自然,10000000分配给-128是最合适的了。
所以,八位二进制数的表示范围是[-128, 127]。八位二进制数就没有128的事了。
[title]怎么得出来的补码?[/title]
老师告诉我们死记住负数的补码就是:除符号位,其余位按位取反再加1。
我们以-1来举例子,正1的补码是0001。我们还是假设:
0001+x=0
我们在前面已经知道是通过溢出来推算出来的x的值是1111。那么,
0001+x=1,0000
x=1,0000-0001
1,0000可以拆成1111+1,所以
x=1111+1-0001
=(1111-0001)+1
二进制中,单独看每一位,1减去一个数(被减数),就相当于把这个数(被减数)取反。
例如:
1-1(被减数)=0(1取反得到的0)
1-0(被减数)=1(取反得到的)
所以:
1111-0001,相当于1110
(1111-0001)+1
=1110+1
=1111
这就是按位取反再加1的由来。
[title]为什么不采用原码?[/title]
正数 + 正数(1+1=2):0001+0001 = 0010(没有问题)
正数 + 负数(1+(-1)=0):0001+1001=1010(-2?显然错误)
[title]为什么补码可以?[/title]
正数 + 正数(1+1=2):0001+0001=0010(没有问题)
正数 + 负数(1+(-1)=0):0001+1111=1,0000(1已经溢出,这里的0000表示补码,翻译为十进制就是0,没有问题)
负数+负数((-1)+(-1)=-2):1111+1111=1,1110(1已经溢出,这里的1110表示补码,翻译为十进制就是-2,没有问题)
既然上面都没问题,说明补码完全可以用在加法和减法中,从而使硬件电路不需要减法器。
[title]计算机CPU底层怎么看待有符号数和无符号数?[/title]
有符号数指带有正负号的数,无符号可以理解为只大于0的数。
参考文献:https://zh.wikipedia.org/wiki/%E4%BA%8C%E8%A3%9C%E6%95%B8
袁春风的《计算机系统基础》