最近在看哈工大刘宏伟老师的《计算机组成原理》,总结其中关于有符号数的几种表示法,顺便感谢老师这么好的公开课。
首先先明确两个概念:
- 真值:带符号的数,如+101,-101
- 机器数:符号数字化的数,如0101,1101
下面结束有符号数的四种表示法
1. 原码表示法
定义:
- 对于整数
[ x ] 原 = { 0 , x 2 n > x ≥ 0 2 n − x 0 ≥ x > − 2 n [x]_{原}=\begin{cases} 0, x & 2^n>x\geq0\\ 2^n-x & 0\geq x>-2^n \end{cases}[x]原={0,x2n−x2n>x≥00≥x>−2n
其中x xx为真值,n nn为整数的位数。
例子:
x = + 1110 [ x ] 原 = 0 , 1110 x=+1110\quad [x]_{原}=0,1110x=+1110[x]原=0,1110
x = − 1110 [ x ] 原 = 2 4 + 1110 = 1 , 1110 x=-1110\quad [x]_{原}=2^4+1110=1,1110x=−1110[x]原=24+1110=1,1110
这里逗号用于分割符号位和数值部分,实际计算机存储中不存在,下同。 - 对于小数
[ x ] 原 = { x 1 > x ≥ 0 1 − x 0 ≥ x > − 1 [x]_{原}=\begin{cases} x & 1>x\geq0\\ 1-x & 0\geq x>-1 \end{cases}[x]原={x1−x1>x≥00≥x>−1
例子:
x = + 0.1101 x 原 = 0.1101 x=+0.1101 \quad {x}_{原}=0.1101x=+0.1101x原=0.1101
x = − 0.1101 x 原 = 1 + 0.1101 = 1.1101 x=-0.1101 \quad {x}_{原}=1+0.1101=1.1101x=−0.1101x原=1+0.1101=1.1101
这里用小数点将符号位和数值位分隔开,下同
Note: [ + 0 ] 原 ≠ [ − 0 ] 原 [+0]_{原}\neq[-0]_{原}[+0]原̸=[−0]原
优点: 简单、直观。
缺点: 没有统一加减法(对于两个数相加,如果用原码表示法,可能需要做加法,也可能需要做减法,对运算器而言比较麻烦。)
2. 补码表示法
优点: 统一加减法
定义:
- 对于整数
[ x ] 补 = { 0 , x 2 n > x ≥ 0 2 n + 1 + x 0 > x ≥ − 2 n ( m o d   2 n + 1 ) [x]_{补}=\begin{cases} 0, x & 2^n>x\geq0\\ 2^{n+1}+x & 0> x\geq-2^n(mod\,2^{n+1}) \end{cases}[x]补={0,x2n+1+x2n>x≥00>x≥−2n(mod2n+1)
其中x xx为真值,n nn为整数的位数。
例子:
x = + 1010 [ x ] 补 = 0 , 1010 x=+1010\quad [x]_{补}=0,1010x=+1010[x]补=0,1010
x = − 1011000 [ x ] 补 = 2 7 + 1 + ( − 1011000 ) = 1 , 0101000 x=-1011000\quad [x]_{补}=2^{7+1}+(-1011000)=1,0101000x=−1011000[x]补=27+1+(−1011000)=1,0101000 - 对于小数
[ x ] 补 = { x 1 > x ≥ 0 2 + x 0 > x ≥ − 1 ( m o d   2 ) [x]_{补}=\begin{cases} x & 1>x\geq0\\ 2+x & 0> x\geq-1(mod\,2) \end{cases}[x]补={x2+x1>x≥00>x≥−1(mod2)
例子:
x = + 0.1110     [ x ] 补 = 0.1110 x=+0.1110\quad\quad\, \,\, [x]_{补}=0.1110x=+0.1110[x]补=0.1110
x = − 0.1100000 [ x ] 补 = 2 + ( − 0.1100000 ) = 1.0100000 x=-0.1100000\quad [x]_{补}=2+(-0.1100000)=1.0100000x=−0.1100000[x]补=2+(−0.1100000)=1.0100000
Note[ + 0 ] 补 = [ − 0 ] 补 [+0]_{补}=[-0]_{补}[+0]补=[−0]补
求补码的快捷方式:
当真值为正时,补码与原码相同;当真值为负时,补码可用原码除符号位外,按位取反,末位再加1得到。
通过补码求原码:
当真值为正时,原码与补码相同;当真值为负时,原码可用补码除符号位外,按位取反,末位再加1得到。
3. 反码表示法
定义:
- 对于整数
[ x ] 反 = { 0 , x 2 n > x ≥ 0 2 n + 1 − 1 + x 0 ≥ x > − 2 n ( m o d   2 n + 1 − 1 ) [x]_{反}=\begin{cases} 0, x & 2^n>x\geq0\\ 2^{n+1}-1+x & 0\geq x>-2^n(mod\,2^{n+1}-1) \end{cases}[x]反={0,x2n+1−1+x2n>x≥00≥x>−2n(mod2n+1−1)
其中x xx为真值,n nn为整数的位数。
例子:
x = + 1101 [ x ] 反 = 0 , 1101 x=+1101\quad [x]_{反}=0,1101x=+1101[x]反=0,1101
x = − 1101 [ x ] 反 = 2 4 + 1 − 1 + ( − 1101 ) = 1 , 0010 x=-1101\quad [x]_{反}=2^{4+1}-1+(-1101)=1,0010x=−1101[x]反=24+1−1+(−1101)=1,0010 - 对于小数
[ x ] 反 = { x 1 > x ≥ 0 2 − 2 − n + x 0 > x ≥ − 1 ( m o d   2 − 2 − n ) [x]_{反}=\begin{cases} x & 1>x\geq0\\ 2-2^{-n}+x & 0> x\geq-1(mod\,2-2^{-n}) \end{cases}[x]反={x2−2−n+x1>x≥00>x≥−1(mod2−2−n)
其中x xx为真值,n nn为小数的位数。
例子:
x = + 0.1101 [ x ] 反 = 0.1101 x=+0.1101\quad [x]_{反}=0.1101x=+0.1101[x]反=0.1101
x = − 0.1010 [ x ] 补 = 2 − 2 − 4 + ( − 0.1010 ) = 1.0101 x=-0.1010\quad [x]_{补}=2-2^{-4}+(-0.1010)=1.0101x=−0.1010[x]补=2−2−4+(−0.1010)=1.0101
Note: [ + 0 ] 反 ≠ [ − 0 ] 反 [+0]_{反}\neq[-0]_{反}[+0]反̸=[−0]反
三种机器数小结
- 最高位为符号位,书写上用“,”(整数)或“.”(小数)将数值部分和符号位隔开。
- 对于正数,原码=补码=反码
- 对于负数,符号位为1,其数值部分将原码数值部分按位取反末位加1—>补码;原码数值部分按位取反—>反码。
4. 移码表示法
补码表示法的不足:
补码很难直接判断其真值的大小。如:x = + 21 , [ x ] 补 = 0 , 10101 ; x = − 21 , [ x ] 补 = 1 , 01011 x=+21, [x]_{补}=0,10101;x=-21,[x]_{补}=1,01011x=+21,[x]补=0,10101;x=−21,[x]补=1,01011;很难根据补码直接判断出两个数真值的大小(需要根据符号位分情况比较)。
移码定义:
[ x ] 移 = 2 n + x ( 2 n > x ≥ − 2 n ) [x]_{移}=2^n+x\quad(2^n>x\geq-2^n)[x]移=2n+x(2n>x≥−2n)
其中x xx为真值,n nn为整数的位数。
例子
x = + 10100 , [ x ] 移 = 2 5 + 10100 = 1 , 10100 ; x=+10100,[x]_{移}=2^5+10100=1,10100;x=+10100,[x]移=25+10100=1,10100;
x = − 10100 , [ x ] 移 = 2 5 − 10100 = 0 , 01100 x=-10100,[x]_{移}=2^5-10100=0,01100x=−10100,[x]移=25−10100=0,01100
Note:
1. 移码与补码只相差一个符号位(符号位取反,数值位相同)
2. [ + 0 ] 移 = [ − 0 ] 移 [+0]_{移}=[-0]_{移}[+0]移=[−0]移
3. 只有整数移码的定义,因为移码主要用于表示浮点数的阶码(阶码都是整数),这样就能很方便的判断浮点数阶码大小。