计算机采用的是二进制,二进制包括两个数码:0,1。
一位二进制数的可能取值有 2 个,k 位二进制数的可能取值就有 个。
在计算机中有多种数据类型,表示整数的数据类型就有好几种:
- 1 字节数,即 8 位二进制数,可能取值有
个;
- 2 字节数,即 16 位二进制数,可能取值有
个;
- 4 字节数,即 32 位二进制数,可能取值有
个;
- 8 字节数,即 64 位二进制数,可能取值有
个。
计算机中的数据类型包括有符号类型和无符号类型,有符号类型的整数称为有符号整数,无符号类型的整数称为无符号整数。
有符号整数中,最高位用于表示符号,因此最高位又称符号位。当最高位是 0 时表示 0 或正整数,当最高位是 1 时表示负整数。除了最高位以外的数位用于表示数字的大小。
无符号整数中,所有的数位都用于表示数字的大小,因此无符号整数不存在负数。
以 1 字节数为例,1 字节数包含 8位二进制数。
对于 1字节的有符号整数,当最高位是 0 时,1 字节数的取值范围是 0 到 127(即 ),当最高位是 1时,1 字节数的取值范围是 -128(即
)到 −1。因此 1 字节的有符号整数的取值范围是 −128 到 127,即对于有符号的 8 位二进制数,取值范围是
到
。
对于 1 字节的无符号整数,可能的最小取值是 0,最大取值是 255(即 ),即对于无符号的 8 位二进制数,取值范围是 0 到
。
通过上述例子可以得到有符号整数和无符号整数的如下结论:
- 有符号整数的取值范围包括负整数、零与正整数,无符号整数的取值范围只包括零与正整数,不包括负整数;
- 在位数相同的情况下,有符号整数可以表示的最大值比无符号整数小了一半;
- 对于 k 位整数,有符号整数的取值范围是
到
,无符号整数的取值范围是 0 到
。
在讲述原码、补码和反码的概念之前,需要先了解两个概念:机器数和真值。
一个数在计算机中的二进制表示形式称为这个数的机器数。机器数是有符号数,机器数的最高位是符号位,0 表示0或正数,1 表示负数。
以 8 位二进制数为例。十进制数 +10
转换成二进制数是 00001010,十进制数 -10
转换成二进制数是 10001010。这里的 00001010 和 10001010 就是机器数。
因为机器数的最高位是符号位,所以机器数的形式值不一定等于真正数值。例如 10001010 的形式值是 138,真正数值是 −10,形式值和真正数值是不同的。为了加以区分,将机器数的真正数值称为机器数的真值。
例如,00000010 的真值是 +2,10000010 的真值是 −2。
原码是机器数的符号位加上机器数的真值的绝对值,最高位是符号位,其余位表示数值。
以 8 位二进制数为例。+10 的原码是 00001010,−10 的原码是 10001010。
8 位二进制数的原码表示的最大值是 01111111,即十进制的 +127,最小值是 11111111,即十进制的 −127,因此 8 位二进制数的原码表示的取值范围是 −127 到 +127。
原码是人脑最容易理解和计算的表示方式。
反码在原码的基础上得到。
0和正数的反码与原码相同,负数的反码是将原码的除了符号位之外的每一位取反,取反即为将 0 变成 1 或将 1 变成 0。
以 8 位二进制数为例。
+10 的原码是 00001010,反码是 00001010;
−10 的原码是 10001010,反码是 11110101。
对于负数,反码的表示方式不直观,通常需要转换成原码才能计算其数值。
补码在反码的基础上得到。
0 和正数的补码与原码、反码相同,负数的补码是在反码的基础上加 1 得到。
以 8 位二进制数为例。
+10 的原码是 00001010,反码是 00001010,补码是 00001010;
−10 的原码是 10001010,反码是 11110101,补码是 11110110。
对于负数,补码的表示方式不直观,通常需要转换成原码才能计算其数值。
至此,我们已经看到计算机中的有符号数的二进制表示有原码、反码和补码三种表示方法,这三种表示方法分别有什么优缺点呢?
人脑可以知道最高位是符号位,但是对于计算机而言,判断符号位将导致运算变得复杂,因此为了简化运算,人们想出了将符号位也参与运算的方法。
原码是人脑最容易理解和计算的表示方式,但是原码存在两个问题:
- 同时存在 +0(即符号位和其余位都是 0)和 −0(即符号位是 1,其余位都是 0)的表示,虽然可以认为 +0 和 −0 是同一个数,但是 0 带符号是没有意义的,而且会导致有两个不同的原码都对应 0;
- 用原码进行减法运算,会导致错误的结果。
反码的引入,解决了原码的减法运算结果错误的问题,但是仍然没有解决同时存在 +0 和 -0 的问题。
补码的引入则同时解决了减法运算错误和同时存在 +0 和 -0 的问题,而且可以多表示一个最小值。在补码表示法中,不存在 -0 的情况。以 8位二进制数为例,0 的补码是 00000000,10000000 表示的是 -128,-128 没有原码和反码的表示(8 位二进制数的原码和反码能表示的最小值是 -127)。由此可见,补码不仅解决了原码和反码的问题,还可以多表示一个最小值。
由于补码具有上述优点,因此计算机采用补码进行运算。