- 计算机与嵌入式系统架构
- 任保全 詹杰 李洪钧 刘述钢 刘琼 贺乾格编著
- 1319字
- 2021-04-02 14:05:57
1.3 计算机中的数值表示
1.3.1 机器数和真值
1.机器数
一个数在计算机中的二进制表示形式,称为该数的机器数。机器数是带符号数,数的最高位存放符号,正数为0,负数为1。
如计算机字长为8位,十进制数+3转换成二进制就是00000011;如果是十进制数-3,则转换成二进制为10000011。此时的00000011和10000011就是机器数。
2.真值
因为机器数的第一位是符号位,所以其形式值不等于真正的数值。如上面的带符号数10000011,其最高位1代表负,其真正数值是-3而不是形式值131(10000011转换成十进制等于131)。所以,为区别起见,将带符号位的机器数对应的真正数值称为机器数的真值。
例如,00000001的真值=+0000001=+1,10000001的真值=-0000001=-1
1.3.2 原码、反码、补码
在计算机中,对一个数进行存储要使用一定的编码方式。机器存储一个具体数字的编码方式包括原码、反码、补码。
1.原码
原码就是符号位加上真值的绝对值,即用第一位表示符号,其余位表示值。如8位二进制数为
[+1]原=00000001 [-1]原=10000001
因为第一位是符号位,所以8位二进制数的取值范围就是
[11111111, 01111111],即[-127,127]。
原码是我们最容易理解和计算的表示方式。
2.反码
反码的表示方法:正数的反码是其本身;负数的反码是在其原码的基础上,符号位不变,其余各位取反。举例如下。
[+1]=[00000001]原=[00000001]反 [-1]=[10000001]原=[11111110]反如果一个反码表示的是负数,我们无法直观地看出它的数值,通常要将其转换成原码再计算其数值。
3. 补码
补码的表示方法:正数的补码是其本身;负数的补码是在其原码的基础上,符号位不变,其余各位取反,最低位加1(即在反码的基础上加1)。
[+1]=[00000001]原=[00000001]反=[00000001]补
[-1]=[10000001]原=[11111110]反=[11111111]补
对于一个补码表示的负数,我们也无法直观地看出其数值,通常也需要将其转换成原码再计算其数值。
1.3.3 原码、反码、补码的关系
计算机可以用3种编码方式表示一个数。对于正数,3种编码方式的结果都相同;对于负数,原码、反码和补码完全不同。
原码是可被人脑直接识别并用于计算的表示方法,为何还设计反码和补码?
在计算时,我们会根据符号位,选择对真值区域进行加减。但对于计算机,加法、减法、乘法已经是最基础的运算,需要尽量简单的设计,而让计算机辨别符号位会使计算机的基础电路设计变得十分复杂,于是有了让符号位也参与运算的方法。根据运算法则,减去一个正数等于加上一个负数,即1-1=1+(-1)=0,所以机器可以只有加法而没有减法,使计算机的运算设计更加简单。但如果用原码表示,让符号位参与计算,减法将会出错,所以计算机内部不使用原码表示一个数。为了解决原码做减法出错的问题,出现了反码。
例如计算十进制的表达式1-1=0。
1-1=1+(-1)=[00000001]原+[10000001]原=[00000001]反+[11111110]反=[11111111]反=[10000000]原=-0
用反码来计算减法,方案可行,但在“0”这个特殊的数值上,会出现+0和-0以及[00000000]原和[10000000]原两个编码。补码的出现,解决了“0”的符号以及两个编码的问题,具体如下。
1-1=1+(-1)=[00000001]原+[10000001]原=[00000001]补+[11111111]补=[00000000]补=[00000000]原
0用[00000000]补表示,没有了-0的问题,而且可以用[10000000]补表示-128。
(-1)+(-127)=[10000001]原+[11111111]原=[11111111]补+[10000001]补=[10000000]补
-1-127的结果应该是-128,用补码方式运算后,[10000000]补就是-128。但需注意,因为实际上是使用以前的-0的补码来表示-128,所以-128并没有原码和反码表示。(对-128的补码表示[1000 0000]补算出来的原码是[00000000]原,这是不正确的)。
使用补码不仅解决了0的符号以及存在两个编码的问题,而且还能够多表示一个最低数,这就是为什么8位二进制,使用原码或反码表示的范围为[-127, +127],而使用补码表示的范围为[-128, 127]。编程中常用的32位int类型,可以表示的范围是[-231, 231-1]。