c语言中减去一个数等于加上这个数的同余数
作者:互联网
以下示例来源于https://www.cnblogs.com/fangle/p/6816829.html
(六)补码实例
好吧,接下来我们就做一做四位二进制数的减法吧(先不引入符号位)
0110(6)-0010(2)【6-2=4,但是由于计算机中没有减法器,我们没法算】
这个时候,我们想想时钟运算中,减去一个数,是可以等同于加上另外一个正数(同余数)
那么这个数是什么呢?从时钟运算中我们可以看出这个数与减数相加正好等于模。
那么四位二进制数的模是多少呢?也就是说四位二进制数最大容量是多少?其实就是2^4=16=10000B
那么2的同余数,就等于10000-0010=1110(14)
既然如此
0110(6)-0010(2)=0110(6)+1110(14)=10100(20=16+4)
OK,我们看到按照这种算法得出的结果是10100
,但是对于四位二进制数,最大只能存放4位(硬件决定了),如果我们低四位,正好是0100(4)
,正好是我们想要的结果,至于最高位的‘1’
,计算机会把他放入psw寄存器进位位中。
8位机则会放在cy
中,x86会放在cf
中(这个我们不作讨论)
这个时候,我们再想想在四位二进制数中,减去2,就相当于加上它的同余数14(至于它们为什么同余,还是建议看《计算机组成原理》)
但是减去
2
,从另外一个角度来说,也是加上(-2)
。即加上(-2)
和加上14
其实得到的二进制结果除了进位位,结果是一样的。如果我们把
1110(14)
的最高位看作符号位后就是(-2)
的补码,这可能也是为什么负数的符号位是‘1’
而不是‘0’
,
而且在有符号位的四位二进制数中,能表示的只有‘-8~7’
,而无符号位数(14)
的作用和有符号数(-2)
的作用效果其实是一样的。
那正数的补码呢?加上一个正数,加法器就直接可以实现。所以它的补码就还是它本身。
下图给出带符号位四位二进制的补码表示法
到这里,我们发现原码,反码的问题,补码基本解决了。
在补码中也不存在负零了,
因为1000表示-8
这是因为根据上面的补码图,做减法时,0001(1)+1111(-1)=0000
我们再也不需要一个1000
来表示负0
了,就把它规定为-8
负数与负数相加的问题也解决了1111(-1)+1110(-2)=1101(-3)
可能说得有点绕,但是实在是没办法。其实我觉得补码还可以这样画。
很优美有没有,如果你想想地理课本,0不就相当于本初子午线,-8不就是180°,而正数相当于西经,负数相当于东经。
(七)为何这样求补码
然后我们再来看看为什么负数的补码的求法为什么是反码+1
因为负数的反码加上这个负数的绝对值正好等于1111,再加1,就是1000,也就是四位二进数的模
而负数的补码是它的绝对值的同余数,可以通过模减去负数的绝对值,得到他的补码。
所以 负数的补码就是它的补码+1。
有点绕吧,只能说很难算清楚,你们还是自己算算吧。还有上面我提到的另外一种算法。
接下来,我要说一下我自己算补码的小技巧。
看上面那个图。
如果我们把-8当成负数的原点。那么-5的补码是多少呢?
-5=-8+3
-5的补码就是-8的补码加3
1000(-8) +0011(3)=1011(-5)
所以完全可以口算出-5的补码是1011
当然,也可以记住-1的补码是1111
口算减法得出
对于八位加法器的话,可以把-128
当补码原点。十六位可以把-32768
当补码原点。
是的,128
是256
(八位二进制数的模)的一半,32768
是65536
(十六位二进数的模)的一半
也很方便有没有,而且简单的是
补码原点总是最高位是
‘1’
,其他位是‘0’
所以做加法总是简单得可以口算。
标签:14,二进制,补码,负数,减去,等于,余数,四位 来源: https://blog.csdn.net/modi000/article/details/113841959