计算机组成原理-定点数的表示和运算
先前的记录:
学习资源:
视频:2019 王道考研 计算机组成原理
计算机组成原理PPT:链接: https://pan.baidu.com/s/1EqL9NmQ-0glDNIFPBfUmVg 密码: sfwg
配套书籍:链接: https://pan.baidu.com/s/1cZx27Gfooj2uAhSP9sbrRA 密码: j5ms
定点数的表示
计算机中参与运算的数有两大类:无符号数和有符号数。
无符号数:整个机器字长的全部二进制位均为数值位,没有符号位,相当于数的绝对值。对于一个,8位二进制数就有 2 8 2^8 28种不同的状态,数的表示范围为0000 0000 ~ 1111 1111 = 1 0000 0000 - 1,0 ~ 255 = 2 8 2^8 28 - 1
有符号数:对于计算机来说,无法通过+或者-来判断一个数是正数还是负数,于是约定在二进制数的最高位,设置一个符号标志。0代表该数为正数,1代表该数为负数。有符号数的机器表示有原码、补码、反码和移码。
约定:用X表示真值,用 [ X ] 原 [X]_原 [X]原表示原码, [ X ] 补 [X]_补 [X]补表示补码, [ X ] 反 [X]_反 [X]反表示反码, [ X ] 移 [X]_移 [X]移表示移码
真值 机器数(可以直接存到机器中)
+ 156 D = 0 1001 1100B
- 156 D = 1 1001 1100B
真值不在乎其具体是哪个进制,主要是它是有符号(形式化的、图形化的符号)的。
定点表示
定点表示:根据小数点的位置是否固定,将数据分为定点表示和浮点表示。
在定点表示中,小数点的位置是固定不变的,做一个简单的约定:
- 对于定点小数来说,小数点在符号位后面
- 对于定点整数来说,小数点在最低位之后
定点小数
对于机器字长为8位,存储数据御道位数不够需要符号扩展进行补0,扩展后不改变原有值。
定点小数符号扩展:低位补0
+ 0.75 D +0.75D +0.75D = 0.11B ----> 存储为011 -----> 符号扩展为01100000
− 0.75 D -0.75D −0.75D = 1.11B ----> 存储为111 -----> 符号扩展为11100000
对于一个n+1位的定点小数,其数值部分为n位,则其数值范围为[ − ( 1 − 2 − n ) -(1 - 2^{-n}) −(1−2−n), 1 − 2 − n 1 - 2^{-n} 1−2−n]。8位定点小数范围即为11111111~01111111,[ − ( 1 − 2 − 7 ) -(1 - 2^{-7}) −(1−2−7), 1 − 2 − 7 1 - 2^{-7} 1−2−7]
定点整数
定点整数符号扩展:符号位后,高位补0
+ 3 D +3D +3D = 011B —> 存储为011 ----> 符号扩展为00000011
− 3 D -3D −3D = 111B —> 存储为111 ----> 符号扩展为10000011
对于一个n+1位的定点整数,其数值部分为n为,则其数值范围为[ − ( 2 n − 1 ) -(2^n - 1) −(2n−1), 2 n − 1 2^n - 1 2n−1]。8位定点整数范围即为11111111~01111111,[ − ( 2 7 − 1 ) -(2^7 - 1) −(27−1), 2 7 − 1 2^7 - 1 27−1]。
由此可见定点小数和定点整数的区别主要是由于小数点的隐含位置而导致的。
原码表示
原码表示是一种比较简单直观的机器数表示方法。可以看成 符号位 + 绝对值
纯小数的原码表示
纯小数原码
x 1 = + 0.8125 , x 2 = − 0.8125 x_1=+0.8125, x_2=-0.8125 x1=+0.8125,x2=−0.8125, 真值(十进制形式)
x 1 = + 0.1101 , x 2 = − 0.1101 x_1=+0.1101, x_2=-0.1101 x1=+0.1101,x2=−0.1101 ,真值(二进制形式)
[ x 1 ] 原 [x_1]_原 [x1]原=0.1101, [ x 2 ] 原 [x_2]_原 [x2]原=1.1101,我们的做法:+换成0,-换成1
[ x 1 ] 原 [x_1]_原 [x1]原=0.1101, [ x 2 ] 原 [x_2]_原 [x2]原=0.1101 + 1.0000 = 1.1101,计算机的做法:“加”(正数和负数其绝对值是相同的,对于计算机来说只需要加上符号位即可)
符号扩展为8位机器字长后:
[ x 1 ] 原 [x_1]_原 [x1]原=0.1101000
[ x 2 ] 原 [x_2]_原 [x2]原=1.1101000
若机器字长为n+1,则原码小数的表示范围为 − ( 1 − 2 − n ) ≤ x ≤ 1 − 2 − n -(1 - 2^{-n})\leq x \leq 1 - 2^{-n} −(1−2−n)≤x≤1−2−n(关于原点对称)
纯整数的原码表示
x 1 = + 14 , x 2 = − 14 x_1=+14, x_2=-14 x1=+14,x2=−14,真值(十进制形式)
x 1 = + 1110 , x 2 = − 1110 x_1=+1110, x_2=-1110 x1=+1110,x2=−1110,真值(二进制形式)
-------> 机器码,需要将图形化的符号处理掉
[ x 1 ] 原 [x_1]_原 [x1]原=0,1110, [ x 2 ] 原 [x_2]_原 [x2]原=1,1110,我们的做法:+换成0,-换成1
[ x 1 ] 原 [x_1]_原 [x1]原=0,1110, [ x 2 ] 原 [x_2]_原 [x2]原=0,1110 + 1,0000 = 1,1110 计算机的做法:“加”
符号扩展为8位机器字长后:
[ x 1 ] 原 [x_1]_原 [x1]原=0,0001110
[ x 2 ] 原 [x_2]_原 [x2]原=1,0001110
若机器字长为n+1,则原码整数的表示范围为 − ( 2 n − 1 ) ≤ x ≤ 2 n − 1 -(2^n-1)\leq x \leq 2^n-1 −(2n−1)≤x≤2n−1(关于原点对称)
补码表示
由于采用原码表示的方式进行加减法比较麻烦,所以可以利用补码表示的方式,统一将加减法变成加法来处理。
先进行有符号数和无符号数的对比,发现求得的结果并不匹配!
此时就需要进行一个补码操作:
对于一个时钟,此时的指针指向10,如果需要将指针调至8处,无非就两种操作方式:
逆时针(减法操作):10 - 2 = 8
顺时针(加法操作):10 + 10 = 20,但是对于时钟来说,其最大的计量容量就是12个单位,所以20这个数据就溢出了,时钟可以记录到的最大数据就是8,也就是一个取模操作:20 mod 12 = 8; 可以发现一个规律,加上的10可以看成,先是加上了这个时钟的最大计量范围12,然后减去了需要操作的数。
最后得出结论:
对于正数来说,其原码和补码相同。
对于负数来说,符号位不变,数值位取反(反码)加上1。
取反加1操作是互逆的!原码 <----> 补码的相互转换都可以通过取反加1实现。
补码的数值范围:
对于正数来说,补码和原码相同,所以正数的范围是一致的
对于负数来说,存在一个取反加1的过程,符号位1不变,在 2 n 2^n 2n - 1的基础上还需要加1,变成 2 n 2^n 2n,再考虑到符号位1,所以,总体来说,补码的范围要比原码的范围多表示一个 − 2 n -2^n −2n,所以补码的数值范围为: − 2 n ≤ x ≤ 2 n − 1 -2^n \leq x \leq 2^n - 1 −2n≤x≤2n−1
反码表示
反码就是原码转换成补码的一个中间过程。
- 对于正数来说,原码和反码相同
- 对于负数来说,符号位不变,数值位取反即可
表示的范围和原码相同。
移码表示
移码就是补码的符号位取反。移码是为了方便比较数的大小,移码保持了数据原有的大小顺序。移码大,真值大。移码小,真值小。
原码、补码、反相互转换
定点数的运算
移位运算
对于10进制数字:100.0
小数点左移2位:1.000,相当于除以100,即除以 1 0 2 10^2 102 数字右移2位
小数点右移1位:1000.,相当于乘以10,即乘以 1 0 1 10^1 101 数字左移1位
计算机是不会提供单独的存储单元存储小数点,所以采用移位的方式
对于一个数,其基数为r,则:
- 数字右移n位,相当于÷ r n r^n rn
- 数字左移n位,相当于 × r n \times r^n ×rn
移位运算根据不同的操作数对象可以分为算术移位和逻辑移位:
-
无符号数:逻辑移位
-
有符号数:算术移位
逻辑移位
逻辑左移时,高位移丢,低位添0;
逻辑右移时,低位移丢,高位添0。
注意:不管是逻辑左移还是逻辑右移都是添0
算术移位
二进制: S K 6 K 5 K 4 K 3 K 2 K 1 K 0 = ( − 1 ) S × ( K 6 × 2 6 + K 5 × 2 5 + K 4 × 2 4 + K 3 × 2 3 + K 2 × 2 2 + K 1 × 2 1 + K 0 × 2 0 ) SK_6K_5K_4K_3K_2K_1K_0 = (-1)^S \times (K_6 \times 2^6 + K_5 \times 2^5 + K_4 \times 2^4 + K_3 \times 2^3 + K_2 \times 2^2 + K_1 \times 2^1 + K_0 \times 2^0) SK6K5K4K3K2K1K0=(−1)S×(K6×26+K5×25+K4×24+K3×23+K2×22+K1×21+K0×20)
在算术移位中,符号位固定不变。
对于原码来说,左移一位如果不产生溢出,相当于乘以2(和十进制的左移一位乘以10类似)。右移一位,如果不考虑因为移出而舍去的末尾尾数,相当于除以2。
算术移位空位填补规则
对于正数来说,原码、补码、反码都相同,所以移位后出现的空位都是以0添补。对于负数,原码、补码、反码的表示形式不同,因此机器数移位的时候,对于空位的添补规则也不同。
溢出判断(加减运算)
设机器字长为8位(含一位符号位),A=15,B=-24,求 [ A + B ] 补 [A+B]_补 [A+B]补和 [ A − B ] 补 [A-B]_补 [A−B]补,C=124,求 [ A + C ] 补 [A+C]_补 [A+C]补和 [ B − C ] 补 [B-C]_补 [B−C]补
[ A + B ] 补 [A+B]_补 [A+B]补= [ A ] 补 [A]_补 [A]补 + [ B ] 补 [B]_补 [B]补
00001111 + 10011000 (原码) -----> 00001111 + 11101000 (补码)= 11110111(补码)
对应的原码就是10001001,真值为-9
[ A − B ] 补 [A-B]_补 [A−B]补= [ A ] 补 [A]_补 [A]补 + [ − B ] 补 [-B]_补 [−B]补
00001111 + 00011000(原码) -------> 00001111 + 00011000(补码)= 00100111(补码)
对应的原码就是 00100111,真值为+39
[ A + C ] 补 [A+C]_补 [A+C]补= [ A ] 补 [A]_补 [A]补 + [ C ] 补 [C]_补 [C]补
00001111 + 01111100(原码) ------> 00001111 + 01111100(补码)= 10001011(补码)
对应的原码就是11110101,真值为-117
[ B − C ] 补 [B-C]_补 [B−C]补 = [ B ] 补 [B]_补 [B]补 + [ − C ] 补 [-C]_补 [−C]补
10011000 + 11111100(原码) --------> 11101000 + 10000100(补码) = 10,1101100(补码)
此时的符号位为0,对应的原码为01101100,真值为+108
方法1(一位符号位)
采用一位符号位
设A的符号位为 A S A_S AS,B的符号位为 B S B_S BS,运算结果的符号位位 S S S_S SS,则溢出逻辑表达式为:
V
=
A
S
B
S
S
S
‾
+
A
S
‾
B
S
‾
S
S
V=A_SB_S \overline{S_S} + \overline{A_S} \overline{B_S}S_S
V=ASBSSS+ASBSSS (注意此时的+
为逻辑符号)
如果V=0,则无溢出。如果V=1,则存在溢出。
对于 [ A + B ] 补 [A+B]_补 [A+B]补情况: V = 010 + 101 = 0 (无溢出)
对于 [ A − B ] 补 [A-B]_补 [A−B]补情况: V = 001 + 110 = 0 (无溢出)
对于 [ A + C ] 补 [A+C]_补 [A+C]补情况: V = 000 + 111= 1(溢出)
对于 [ B − C ] 补 [B-C]_补 [B−C]补情况:V = 111 + 000 = 1 (溢出)
方法2(符号进位+最高数进位)
采用一位符号位,根据数据位的进位情况判断溢出符号位的进位 C s C_s Cs,最高数位的进位 C 1 C_1 C1
符号位的最高位进位 C s C_s Cs
数值位的最高位进位 C 1 C_1 C1
符号位的进位 C s C_s Cs | 最高数位的进位 C 1 C_1 C1 | |
---|---|---|
上溢 | 0 | 1 |
下溢 | 1 | 0 |
对于 [ A + C ] 补 [A+C]_补 [A+C]补,两个较大的数相加,A的符号位为0,B的符号位为0,在补码相加过程中,A的补码和B的补码的数值位产生了进位,此时最高数为的进位 C 1 = 1 C_1 = 1 C1=1,对于符号位始终保持在1那个位置上,所以无进位,符号位的进位 C s = 0 C_s = 0 Cs=0。
[ B − C ] 补 [B-C]_补 [B−C]补,数值位并没有产生进位,所以 C 1 = 0 C_1 = 0 C1=0,产生进位的是符号位,从0变成了10,此时符号位的进位 C s = 1 C_s = 1 Cs=1
方法3(双符号位)
采用双符号位,正数符号位为00,负数符号为11
采用双符号位的移位运算:低位符号位参与运算,高位符号位代表真正的符号
[ A + C ] 补 [A+C]_补 [A+C]补 ------> 000001111 + 001111100(补码)= 010001011 上溢
[ B − C ] 补 [B-C]_补 [B−C]补 ---------> 111101000 + 110000100(补码) = 1001101100 下溢
[ A + B ] 补 [A+B]_补 [A+B]补 -----------> 000001111 + 111101000(补码) = 111110111 无溢出
[ A − B ] 补 [A-B]_补 [A−B]补 -----------> 00001111 + 00011000(补码)= 000100111 无溢出
符号位 S S 1 S S 2 S_{S_1}S_{S_2} SS1SS2的各种情况:
- S S 1 S S 2 S_{S_1}S_{S_2} SS1SS2 = 00:表示结果为正数,无溢出;
- S S 1 S S 2 S_{S_1}S_{S_2} SS1SS2 = 01:表示结果正溢出;
- S S 1 S S 2 S_{S_1}S_{S_2} SS1SS2 = 11:表示结果为负数,无溢出;
- S S 1 S S 2 S_{S_1}S_{S_2} SS1SS2 = 10:表示结果负溢出;
此时的溢出判断表达式为 V = S S 1 ⨁ S S 2 V=S_{S_1}\bigoplus S_{S_2} V=SS1⨁SS2,V=0无溢出,V=1有溢出。
乘除
乘法
原码一位乘法
设机器字长位5位(含一位符号位,n=4),x=-0.1101,y=+0.1011,采用一位原码乘法求x.y
最终结果的符号位 = x s ⨁ y s x_s \bigoplus y_s xs⨁ys
我们的做法:
机器的做法:
补码一位乘法
除法
我们的做法:
机器的做法有点复杂…详情可以看王道的书,具体就不写在博客了。
强制类型转换
有符号数和无符号数转换
输出显示为x=-4321, y=61215。
不同字长整数的转换
长字长变量 —> 短字长变量
输出结果:
x = 165537, y = -31071
u = -34991, v = 30545
其中x, y, u, v的十六进制表示分别为:0x000286a1、0x86a1、0xffff7751、0x7751
很容易可以看出,当长字长变量转成短字长变量强制转换的事后,系统将高位子长部分直接阶段,低位直接赋值。
短字长变量 —> 长字长变量
输出结果:
x=-4321, y=-4321
u=61215, v=61215
其中x, y, u, v的十六进制表示分别为:0xef1f、0xffffef1f、0xef1f、0x0000ef1f
当短字长变量强制转换成长字长变量后,低位的权值保持不变,在位值相等的情况下,还需要补充高位的符号位。
当char类型为8位的ASCII码整数的时候,转换成int类型只需要在高位补0即可。