整数的表示其实是比较简单的,无非是解决符号位、数字表示的唯一性等问题
整数在计算机中是使用补码表示的,在讲解补码前,先看一下相关概念。
机器数与真值
数值在计算机中的表现形式叫做机器数,该数值就是机器数代表的真值。机器数是真值在计算机中的表现形式,真值是机器数的代表的数值。
比如5在计算机中的表现形式是00000101,所以00000101就是5的机器数,5就是机器数00000101所代表的真值。
整型数在计算机中的编码方式
C语言中的整型数分为有符号数和无符号数两种类型,无符号数代表的都是非负整数,所以在计算机中直接用二进制值表示就可以,但是有符号数既可以表示正整数,也可以表示负整数,所以有符号数在计算机中不能直接用二进制值来表示,需要使用补码的方式来表示。
有符号数在计算机中的编码方式
编码方式是为了解决有符号数在计算机中的表示方式。计算机中的编码方式主要有原码,反码,补码三种方式。
原码
假定机器字长4字节,原码的编码方式规定如下:
最高位是符号位,用0代表正数,用1代表负数,其它位就是真值的绝对值对应的二进制值,比如十进制数5的二进制值是101,又因为5是正数,所以最高位是0,其它位是0000000 00000000 00000000 00000101,完整格式如下:00000000 00000000 00000000 00000101。
上面描述了正数的原码,下面我们看一下负数的原码,比如-5,因为它是负数,所以最高位用1表示,又因为-5的绝对值是5,所以它的绝对值是101,因为它的原码是10000000 00000000 00000000 00000101。但是原码有两个问题,一个是0有两种表示方式,这不符合数学习惯,另一个问题是[5]原+[-5]原=[10000000 00000000 00000000 00001010]原=-10!=0,所以使用原码无法实现正负数的加法运算,也就是说不能实现5-5=0。
反码
为了解决原码中两个正负数相加不等于0的问题,人们设计了反码,反码的规定如下:
正数的反码就是原码,负数的反码最高位是符号位,其它位是它所对应的原码除符号位之外,其它位全部取反。就是原码中除符号位外,0变1,1变0。比如5的原码是00000000 00000000 00000000 00000101,因为5是正数,所以它的反码和原码一样。再比如-5的原码是10000000 00000000 00000000 00000101,因为它是负数,所以除了符号位,其它全部取反,所以它的反码是11111111 11111111 11111111 11111010,所以5-5=[00000000 00000000 00000000 00000101]反+[11111111 11111111 11111111 11111010]反=[11111111 11111111 11111111 11111111]反 = -0,因为0无所谓正负,所以它代表的就是0,所以反码解决了原码相对数相加不等于0的问题,但是,0分为正0和负0不符合数学习惯,所以人们继续改进,发明了补码。
补码
正数的补码和原码、反码一样,负数的补码为它的反码加1,所以5-5=5+(-5)=[00000000 00000000 00000000 00000101]反+[11111111 11111111 11111111 11111010]反= 00000000 00000000 00000000 00000101]补+[11111111 11111111 11111111 11111011]补= [00000000 00000000 00000000 00000000]补=0,所以补码解决了正负数相加不等于0的问题,又因为-0的反码加1和+0的补码一样,所以在补码中,0只有一个,就是[00000000 00000000 00000000 00000000]补,因此,在计算机中有符号数采用补码表示。
补码的数学原理
假设在计算机中用一个字节来表示整数,那么总共可以表示256个整数,如果这些数都是无符号数,那么表示范围是0~255。所以如果是两个无符号数相加,CPU设计就会非常容易,直接对这两个数做二进制运算就可以,但是,有符号数怎么办,因为有符号数涉及符号位的表示,减法的运算,所以如果用正常的逻辑思路去设计CPU的运算器,就需要解决符号位和减法运算的问题,这样CPU的设计就会非常麻烦,而且效率也不高,因此,有人想到了同余数的概念,同余数告诉我们在有限的连续变化空间内,一个二进制数代表的不仅是这一个数,而是与这个值同余的所有整数,比如11111111这个数既可以表示255,也可以表示-1,为什么呢?因为在1个字节存储空间的情况下,-1和255模256相等。又因为同余数的两个性质,一个是数a本身就是自己的同余数,另一个就是如果两个数a和b对m同余,并且c和d也是对m同余,那么,a+c和b+d对m同余。同余的本质就是说这些数对应的位置相同,因此,两个数a和b的减法,就可以表示成a和(-b)对m的补码的加法,
并且它们对应的结果一样,这样就可以将有符号的减法运算转换为无符号的加法运算。下面,我们再具体论证一下,为什么它们的结果相等?因为a和自己是同余数,所以a和a对256同余,又因为-b和-b的补码对256同余,所以a-b和a+(-b的补码)对256同余,又因为同余代表的是同一个位置,所以a-b的结果与a+(-b的补码)的结果一样,因此,补码利用同余数的原理将有符号的减法转换为无符号的加法,从而简化了CPU运算器的设计。
原文传送门:请点击