原码、反码、补码
机器数 和 真值
- 机器数:
一个数在计算机中的二进制表示形式, 叫做这个数的机器数。
机器数是带符号的,在计算机用一个数的最高位,称为符号位:用来存放符号, 正数为0, 负数为1.
例如:十进制中的数 +3 ,假设计算机字长为8位,转换成二进制就是:00000011 ;如果是 -3 ,就是 10000011;这里的 00000011 和 10000011 就是机器数(其实就是原码 表示形式) - 真值:
因为第一位是符号位,所以机器数的形式值就不等于真正的数值。例如上面的有符号数 10000011,其最高位1代表负,其真正数值是 -3 而不是 “无符号数” 131(二进制数:10000011 转换成十进制等于131)。所以,为区别起见,将带符号位的机器数对应的真正数值称为机器数的真值(符号位直接按照0或者1 转换成 “+”“-” 占一个位置);例如:0000 0001的真值 = +000 0001 = +1;1000 0001的真值 = –000 0001 = –1;所以 二进制表示形式:10000011 --> - 000 0011 它的真值为 -3 ;其二进制结果为 131,
原码、反码、补码的基础
-
对于一个数,计算机要使用一定的编码方式进行存储:原码,反码,补码是机器存储一个具体数字的编码方式;既然有三种存储形式,那么计算机会选取哪种通用形式呢?答案是:选取补码,即数值在计算机中是以补码的形式来存储的,下面分步来说明为什么要用补码来存?
-
原码:
(1)原码(true form)是一种计算机中对数字的二进制定点表示方法。原码表示法在数值前面增加了一位符号位(即最高位为符号位):正数该位为0,负数该位为1(0有两种表示:+0和-0),其余位表示数值的大小!比如如果是8位二进制 1 :
[+1]原 = 0000 0001
[-1]原 = 1000 0001
(2)因为第一位是符号位,所以8位二进制数的取值范围就是:
[1111 1111 , 0111 1111]
#换成 数字为:
[-127 , 127]
(3)原码的优缺点:优点是简单直观,大脑最容易理解,例如,我们用8位二进制表示一个数,+11的原码为00001011,-11的原码就是10001011;缺点就是:原码不能直接参加运算,如果运算可能会出错。例如:数学上,1+(-1)=0,而在二进制中:
00000001+10000001=10000010 # 换算成十进制为-2 ;这显然出错了
所以原码的符号位不能直接参与运算,必须和其他位分开,这就增加了硬件的开销和复杂性
- 反码:
正数的反码还是其本身;负数的反码是在其原码的基础上,符号位不变,其余各个位取反
[+1] = [00000001]原 = [00000001]反
[-1] = [10000001]原 = [11111110]反
'''
如果一个反码表示的是负数, 除了直观的看到它的最高位是1,它表示是个负数外,
我们无法直观的得出来它的具体数值,通常要将其转换成原码再计算
这里假如直接将负数的二进制反码,按:最高位为符号位“-” 剩下的位数按照二进制来转换的话
'''
11111110 --> -126 显然也不是原来的值 -1
- 补码:
正数的补码还是其本身;负数的补码是其反码+1(也即是:在其原码的基础上, 符号位不变, 其余各位取反, 最后+1)
[+1] = [00000001]原 = [00000001]反 = [00000001]补
[-1] = [10000001]原 = [11111110]反 = [11111111]补
# 如果一个补码表示的是负数, 除了直观的看到它的最高位是1,它表示是个负数外,
# 我们无法直观的得出来它的具体数值,通常要将其转换成原码再计算
# 这里假如直接将负数的二进制补码,按:最高位为符号位“-” 剩下的位数按照二进制来转换的话
11111111 --> -127 显然也不是原来的值 -1
- 计算机为什么选用以补码的形式来存储?
(1)计算机只有加法运算,没有设置减法运算!原因是:对于计算机,加减乘数已经是最基础的运算,要设计的尽量简单;计算机辨别"符号位"显然会让计算机的基础电路设计变得十分复杂!于是人们想出了将符号位也参与运算的方法;我们知道,根据运算法则:减去一个正数等于加上一个负数,即: 1-1 = 1 + (-1) = 0;所以机器可以只有加法而没有减法,这样计算机运算的设计就更简单!
那么计算机要选取哪种码值来做加法运算呢?我们先来一一尝试,并看结果为什么要选择补码!
# 先补充:计算机是如何计算 减法 的,看下面的例子(这里我们假设已经知道是选取补码来运算)
# 求:1-2 的值
# 首先:将1-2 变成 1+(-2),然后分别将1的补码和-2的补码拿来运算
0000 ... 0001 (正数 1补码还是本身)
+
1111 ... 1110 (-2 的补码)
=
1111 ... 1111 (补码)
# 上面结果一看,不对啊,怎么不是-1啊?不急,有规定,我们先看最高位符号位为1,说明它是个负数
# 如果得到的是负数的话,我们需要将它转换成原码的表示形式,如果是正数(最高位符号位为0)则不需要
# 所以我们接着做:
1111 ... 1111 (补码)
1111 ... 1110 (反码)
1000 ... 0001 (原码)
即结果为-1
(2)如果选择 原码来 存储:
# 假设要计算十进制的表达式: 1-1=0
1 - 1 = 1 + (-1) = [00000001]原 + [10000001]原 = [10000010]原 = -2
'''
所以如果用原码表示, 让符号位也参与计算, 显然对于减法来说, 结果是不正确的,
这也就是为何计算机内部不使用原码表示一个数
'''
(3)如果选择 用 反码 来存储:
# 同样假设要计算十进制的表达式: 1-1=0
1 - 1 = 1 + (-1) = [0000 0001

最低0.47元/天 解锁文章
1637





