序
计组 Pre 开始了,但是我把上学期学的内容都忘了(
所以先从数制开始吧。
机器数
一个数在计算机中的二进制表示形式被称为机器数。
机器数是有符号的,计算机中将机器数的最高位(最左边)称为符号位,用以表示符号。0 表示正数,1 表示负数。
真值
机器数的真值是指该机器数对应的实际数值。
对于一个有符号数,它的机器数未必等于它本身。
譬如十进制数 -7,它的机器数为 10000111,但 10000111 如果当作二进制表示,对应的十进制数是 135。故 -7 的机器数的真值应该是 00000111。
原码
原码就是符号位和真值的组合。即用最高位表示符号,其余位表示数字大小。
-
[+1]原码:0000 0001
-
[-1]原码:1000 0001
反码
反码的表示方法如下:
-
正数的反码是其原码本身。
-
负数的反码将其原码的符号位不变,其余各位按位取反。
比如: -
[+1]反码:0000 0001
-
[-1]反码:1111 1110
补码
补码的表示方法如下:
-
正数的补码是其原码本身。
-
负数的补码是其反码加 1。
注意
加 1 指的是二进制加法,注意进位。
比如:
-
[+1]补码:0000 0001
-
[-1]补码:1111 1111
为什么要这么复杂?
数字存储在计算机中,是需要用来运算的。根据四则运算的性质,人们只需要解决加法的运算方法就可以了。
可是,对于人脑而言,进行有符号数的加法是很简单的,因为大家都能一眼看出数字的符号,再根据符号决定运算。对于计算机而言,倘若要模拟人的运算,就必须拥有识别符号的能力,这无疑是增加了复杂度。
于是聪明的人们就想到了把符号位也纳入运算中。
原码运算
大家都知道,1 - 1 = 0。
如果使用原码运算,那么 1 - 1 = 1 + (-1) = 0000 0001 + 1000 0001 = 1000 0010。
按照原码的定义,这显然等于 -2。因此,原码是不行的。
反码运算
仍然是 1 - 1 = 0 这个问题。
1 - 1 = 1 + (-1) = 0000 0001[反码] + 1111 1110[反码] = 1111 1111[反码] = 1000 0000[原码] = -0。
-0,人们都知道 0 和 -0 是一样的,可如果使用反码运算,-0 和 0 就成了两个数。如果用 -0 和 0 分别进行一些运算:
-
-0 + 1 = 1111 1111[反码] + 0000 0001[反码] = 1 0000 0000[反码]
对于反码的加法运算,倘若位数溢出,则需要把溢出的位数依次补到末尾,称之为循环进位。
故 1 0000 0000[反码] = 0000 0001[反码] = 0000 0001[原码] = 1。 -
0 + 1 = 0000 0000[反码] + 0000 0001[反码] = 0000 0001[反码] = 0000 0001[原码] = 1。
可见,反码的运算是繁琐而有歧义的,问题就出在 0 和 -0 的区分上。
补码运算
1 - 1 = 1 + (-1) = 0000 0001[补码] + 1111 1111[补码] = 1 0000 0000[补码]
补码运算中,没有循环进位,溢出位舍弃。
故 1 0000 0000[补码] = 0000 0000[补码] = 0000 0000[原码] = 0。
补码中是没有 0 和 -0 的区分的:0 就是 0000 0000,而 1000 0000 则被用来表示 -128。
为什么是 -128?
-1 + (-127) = 1111 1111 + 1000 0001 = 1000 0000 = -128。
补码是可以解决问题的。
关于原码、反码和补码的数学原理探讨,您可参考这篇文章。