[科普]原码,反码,补码由来

         今天看到原码,反码和补码,突然发现还是有点云里雾里,就重新复习了一下。

         在计算机内部,所有信息都是用二进制数串的形式表示的整数。是整数就有正负之分,而这个正负也需要用二进制来表示,所以一般会用最高有效位作为符号位,0表示正号、1表示负号。这种正负号数字化的机内表示形式就称为“机器数”,而相应的机器外部用正负号表示的数称为“真值”,将一个真值表示成二进制字串的机器数的过程就称为编码

         带符号整数有原码、反码、补码、移码等几种编码方式:

1)        原码的特点就是编码简单直观,与真值转换非常方便。

2)        反码很少会被用到,他主要的用途就是作为原码与补码的一个桥梁。

3)        补码和原码是互补的关系,补码和原码同余,即互为补码。就是说补码和原码的数值位相加,刚好能使数值位全为0并且进1。【这里引入另一个概念——模数,模数从屋里意义上讲是某种计量器的容量。这里我们经常举的一个例子就是钟表,其模数为12,即每到12就重新从0开始。数学上叫取模或求余(mod),一般的程序语言用%表示求余操作。】

4)        移码,又叫增码,是符号位取反的补码,一般用做浮点数的阶码,引入的目的是为了保证浮点数的机器零为全0。

 

         他们之间的转换如下:

十进制

43

-43

二进制

101011

-101011

原码

00101011

10101011

反码

00101011

11010100

补码

00101011

11010101

移码

10101011

01010101

         如上表所示,X真值十进制表示为43,二进制表示为101011,-X为-43和-101011。

l  当X真值为正时,原码、反码、补码完全相同;

l  当X真值为负时,反码的符号位不变,其他各位取反;补码则是反码加1;

l  移码不管正负,只要将补码的符号位取反即可。

 

         在计算机中,数据是以补码的形式存储的。那为什么不用原码和反码呢?

         对于一个8字节的整数(int)来说,范围是2的8次方,表示-128~127。如下面的表格所示,如果用原码和反码,+0和-0是同一个数却有两个不同的表示,这样不仅会使计算机多一层处理,还会浪费一个表示范围;而补码就能很好的解决这个问题。(-128只有补码,而没有原码和反码,因为数值位只能表示0~127

 

编码

真值

编码

真值

 

原码

00000000

0

10000000

-0

 

00000001

1

10000001

-1

 

00000010

2

10000010

-2

 

01111111

127

11111111

-127

 

反码

00000000

0

11111111

-0

 

00000001

1

11111110

-1

 

00000010

2

11111101

-2

 

01111111

127

10000000

-127

 

补码

00000000

0

00000000

-0

11111111 + 1

00000001

1

11111111

-1

11111110 + 1

00000010

2

11111110

-2

11111101 + 1

01111111

127

10000001

-127

10000000 + 1

 

 

10000000

-128

 

 

         除了表示范围更全以外,补码还有很多特性,能给符号运算带来便利,如下:   【其中最有名的就是补码能把减法转化成加法,提高CPU的效率】

         [X],表示X的补码;|X|,表示X的绝对值。

当X < 0 时[X]补 = 28 - |X|;

当X >=0 时[X]补 = |X| =X;

[X+Y]补 = [X]补 + [Y]补;

[X-Y]补 = [X]补 - [Y]补 = [X]补 + [-Y]补;

[X*Y]补= [X]补 * [Y]补 (两真数相乘的补码等于补码的相乘)

正数的补码取反加1后,为其对应的负数的补码;负数的补码取反加1后为其绝对值的补码。


参考博文:http://www.toceansoft.com/relevance/4316.jhtml


你可能感兴趣的:(补码,反码,原码,移码,加法代替减法)