有任何不懂的问题可以评论区留言,能力范围内都会一一回答
继上一章,我们思考一下为啥补码可以去做减法a+(-b),但是原码不行呢?
首先我们思考问题本身是什么,是符号位导致出错了。
那我们看补码,比如说计算a+(-b)(a>0,b>0)且a,b值都不超出数值位大小范围
我们所有的原码补码反码都用xy表示,其中x表示符号位取值范围是(0或者1),y代表数值位范围是(x000 0000)0~255(x111 1111),
a的补码就是0a(a是非负数,原码反码补码相同)
-b的原码是1b
-b的反码是1(255-b)
由于反码是数值位取反,因此取反前后数值位相加之和就是 111 1111(255)
-b的补码就是1(256-b)
但是这个地方好处是什么,是因为256刚好是也就是符号位的一
我们这个地方假设数值位可以为负,那么
-b的补码就是1 0(-b)
这个地方溢出的1被截断,而符号位为0,数值位为-b,这个时候代表的值还是-b,但是符号位变成0,变成正的了,这个地方就把负数和负数的符号位统一了,但是呢,由于数值位不能为负数,所以表示成256-b但是本质上1(256-b)和0(-b)代表的值相同。
因此虽然负数补码和原码求得的方法不同
但本质上无论是负数还是正数的补码和原码代表的值是一样的
这也就是为什么补码计算的值是正确的,并且补码参与计算能够准确无误
本质上补码和反码只是换了一个表示方式,但是表示的值的大小从未改变
-b的补码就是 0(-b)
a的补码就是 0 a
两者相加得到 0(a-b)
刚好正确
同样 a的补码就是 0a
-b的补码就是 1(256-b)
两者相加得到 1(256+a-b)
把256往前面提 10(a-b)
溢出位1被截断,因此变成 0(a-b)
(1)a>b (a-b)>0 数值位值为正
故0(a-b)的补码是0(a-b)
代表的值是a-b=a-b
(2)a<b (a-b)<0 数值位为负
因此 0(a-b)-----> 1(b-a)
1(b-a)的补码是 1(b-a)
代表的值是-(b-a)=a-b
无论哪种情况计算的结果的值都是一样的
从而也反向验证了假设的可行性
因此这个地方也就能解释为啥非负数原码反码补码相同,而负数却需要变化,原因是因为补码是把所有数的符号位全部变成0参与计算,从而避免符号位的影响,但是非负数的符号位本身就是0,所以非负数的原码反码补码都相同啊!