计算机二进制数值表示为何出现原码反码补码三种方式? and 如何计算?

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/evolone/article/details/70237456

前言:
学习计算机的同学,在底层硬件计算过程中会遇到原码、反码、补码。很多关于计算机的书籍都介绍原码、反码、补码的表示方法,及相互转换关系,但是同一个值为什么要用到原码、反码、补码却没详细说明。为什么要使用这三种不同的编码表示同一个数?它们的原理是什么呢?我搜索了论文资料,在前人基础上,终于弄明白了这些问题,现收集整理如下。

一、原码
我们知道数值在计算机中表示形式为机器数,由0和1组成,计算机只能识别0和1,使用的是二进制。而在日常生活中人们习惯使用十进制,并且我们用的数值有正负之分。于是在计算机中就用一个数的最高位存放符号(0为正,1为负)。这就是机器数的原码了。

有了数值的表示方法,计算机就可以对数进行算术运算,但是很快就发现用带符号位的原码进行乘除运算时结果正确,而在加减运算的时候就出现了问题,如下:

假设数据位宽为8bits

(1) 10 - (1)10 = (1)10 + (-1)10 = (0)10

(0 0000001)原 + (1 0000001)原 = (1 0000010)原 = ( -2 ) 计算错误

因为在两个整数的加法运算中是没有问题的,于是就发现问题出现在带符号位的负数身上。

二、反码
对除符号位外的其余各位逐位取反就产生了反码。反码的取值空间和原码相同且一一对应。
下面是反码的减法运算:

(1)10 - (1)10 = (1)10 + (-1)10 = (0)10

(0 0000001)反 + (1 1111110)反 = (1 1111111)反 = ( -0 ) 计算错误

(1)10 - (2)10 = (1)10 + (-2)10 = (-1)10

(0 0000001)反 + (1 1111101)反 = (11111110)反 = (-1) 正确。

问题出现在(+0)和(-0)上,在人们的计算概念中零是没有正负之分的。古代印度人首先将零作为标记并放入运算之中,包含有零号的印度数学和十进制计数对人类文明的贡献极大,不得不感慨下,阿三也是有贡献的。

三、补码
于是就引入了补码。
正数的原反补都一样;负数的补码就是对反码加一。

注意:
负数计算补码的方法为原码的符号位不变,数值位按位取反,之后再加一
例子:
十进制的-2
(1)由原码计算补码
原码= (1 000_0010)原
补码= 原码符号位不变数值位取反+1=(1 111_1101)反+1=(1 111_1110)补
(2)由补码计算原码
补码=(1 111_1110)补
原码=补码符号位不变数值位取反+1=1 000_0001+1=(1 000_0010)原

在补码中用(-128)代替了(-0),这个是人为规定的。

所以补码的表示范围为:

(-128~0~127)共256个。

注意:(-128)没有相对应的原码和反码, (-128) = (1 0000000) 补码的加减运算如下:

(1)10 - (1)10 = (1)10 + (-1)10 = (0)10

(0 0000001)补 + (1 1111111)补 = (0 0000000)补 = ( 0 ) 正确。

(1)10 - (2)10 = (1)10 + (-2)10 = (-1)10

(00000001)补 + (11111110)补 = (11111111)补 = (-1) 正确。

四、运算
计算机中的二进制计算可采用原码运算和补码运算。
特别注意原码计算与补码计算处理减法时的不同。

减法运算

(1)补码运算:
A-B = A + (~B) +1
其中,~B是B按位取反得到的,包括符号位都要取反
这里的取反与取反码是不同滴!
取反码,符号位不变,只取反数值位!
比如:

10进制:
1-(-2)= 1 + 2 = 3

2进制:
0 000 0001 (二进制1的原码)- 1 000 0010 (二进制-2的原码)
= 0 000 0001(二进制1的补码) - 1 111 1110 (二进制-2的补码)
= 0 000 0001 (二进制1的补码)+ 0 000 0001(二进制-2补码的按位取反,符号位也取反) + 0 000 0001(二进制1的补码)
= 0 000 0011(二进制3的补码)

(2)原码运算:
A-B = A + (-B)
其中,-B是将B的符号位取反,数值位不变

五、总结

补码的设计目的是:

⑴ 使符号位能与有效值部分一起参加运算,从而简化运算规则。补码机器数中的符号位,并不是强加上去的,是数据本身的自然组成部分,可以正常地参与运算。

⑵ 使减法运算转换为加法运算,进一步简化计算机中运算器的线路设计,减少硬件设计复杂度,降低芯片面积,减少功耗。

另外,所有这些转换都是在计算机的最底层进行的,而在我们使用的汇编、c等其他高级语言中使用的都是原码。

所以,大家看了上面这些应该对原码、反码、补码有了新的认识了吧!

猜你喜欢

转载自blog.csdn.net/evolone/article/details/70237456
今日推荐