[计算机组成原理] 02 数据的表示和运算(2)
文章目录
定点数的表示
定点数:小数点的位置固定 eg: 996.007 ——常规计数
浮点数:小数点的位置不固定 eg: 9.96007* 1 0 2 10^2 102 ——科学计数法
无符号数的表示
无符号数:整个机器字长的全部二进制位均为数值位,没有符号位,相当于数的绝对值。
无符号数表示范围的求解:
设8位无符号数的最大值1111 1111为x,x+1= 2 8 2^8 28,所以 x= 2 8 2^8 28-1
通常只有无符号整数,而没有无符号小数。
有符号数的定点表示
原码
原码:用尾数表示真值的绝对值,符号位“0/1”对应“正/负”
隐含小数点之前的一个位置的位权是 2 0 2^0 20,隐含小数点之后的一个位置的位权是 2 − 1 2^{-1} 2−1
真值0有+0和-0两种形式。
原码小数表示范围的求解:
2 − 1 2^{-1} 2−1+ 2 − 2 2^{-2} 2−2+ 2 − 3 2^{-3} 2−3+…+ 2 − n 2^{-n} 2−n=1- 2 − n 2^{-n} 2−n
反码
反码:若符号位为0,则反码与原码相同
若符号位为1,则数值位全部按位取反
反码只是原码转变为补码的一个中间状态,实际中并没有什么用处。
补码
补码:正数的补码=原码
负数的补码=反码末位+1(要考虑进位)
将负数的补码转回原码的方法相同:尾数取反,末位+1
移码
移码:补码的基础上将符号位取反。注意:移码只能用于表示整数
移码的特性保证了可以用计算机硬件很方便地实现两个移码之间的大小对比。
比较两个移码大小可以从最高位的bit开始,依次往后对比,谁先出现1谁就是更大的;如果都出现1,就继续向后对比。
在之后学习的浮点数中,会大量使用移码。
练习
回顾复习
原码补码移码的作用
上面我们只是介绍了如何求原码补码移码,这一节我们来看它们的作用。
计算机硬件对原码进行加减运算时,必须考虑符号位。当符号位为1时,要将加法转换成两个正数的减法来做。
减法的硬件实现困难。同时设计加法和减法,会使得硬件的成本和复杂度增加。
那么,能否用加法代替减法?
通过上面模运算的性质可以看出,是可以用加法来等价代替减法的。
我们假设计算机的机器字长为8 bit,表示范围为0 ~ 2 8 2^8 28-1。当运算超过这个范围时,计算机只会保留最低的八位,就相当于mod 2 8 2^8 28
补码的作用:使用补码可以将减法操作转变为等价的加法,ALU中无需集成减法器。执行加法操作时,符号位一起参与运算。
移码的作用见上一小节。
移位运算
算术移位
移位:通过改变各个数码位和小数点的相对位置,从而改变各数码位的位权。可用移位运算实现乘法、除法。
原码的算术移位
右移:高位补0,低位舍弃。若舍弃的位=0,则相当于÷2;若舍弃的位≠0,则会丢失精度。
左移:低位补0,高位舍弃。若舍弃的位=0,则相当于×2;若舍弃的位≠0,则会出现严重误差。
定点整数和定点小数的原码移位运算是相同的。
反码的算术移位
补码的算术移位
只要遵循上面的规定,无论使用的是什么码,左移就相当于×2,右移就相当于÷2
由于位数有限,因此有时候无法用算术移位精确地等效乘除法。
算术移位的应用举例
逻辑移位
逻辑移位的应用举例
循环移位
循环左移:1 0 1 1 0 1 0 1 ——> 0 1 1 0 1 0 1 1
循环右移:0 1 1 0 1 0 1 1 ——> 1 0 1 1 0 1 0 1
带进位位的循环左移:1 1 0 1 1 0 1 0 1 ——> 1 0 1 1 0 1 0 1 1
把数值位的最高位放到进位位,原本的进位位补充出现的空位。
加减运算和溢出判断
原码的加减运算
原码的加减运算逻辑太复杂,用硬件实现太难了。
所以我们用补码来实现加减运算。
补码的加减运算
溢出判断
方法1
A s A_s As表示被加数的正负号, B s B_s Bs表示加数的正负号, S s S_s Ss表示最终运算结果的正负号。
方法2
只要发生了溢出,符号位的进位 C S C_S CS和最高数值位的进位 C 1 C_1 C1肯定是不同的。用异或运算来判断是否不同。
方法3
发生溢出的时候,其实是说明给定的机器字长位数不够表示那么大的范围。
如何表示更大范围的数,从而避免溢出呢?
原码的乘法运算
乘法运算的实现思想
手算乘法(十进制)
手算乘法(二进制)
二进制的原码乘法实现起来要比十进制还要方便,因为二进制的乘数每一位只有可能出现0或者1这样的两种情况,如果出现1,那么这次得到的位积就刚好和被乘数是一样的;如果出现的是0,那么这次得到的位积直接取全0就可以。
原码一位乘法
设机器字长为 n+1=5位(含一位符号位), [ x ] 原 [x]_原 [x]原=1.1101, [ y ] 原 [y]_原 [y]原=0.1011,采用原码一位乘法求 x x x · y y y
符号位单独处理:符号位= x s x_s xs ⊕ \oplus ⊕ y s y_s ys 数值位按取绝对值进行乘法计算 [ ∣ x ∣ ] 原 [|x|]_原 [∣x∣]原=0.1101, [ ∣ y ∣ ] 原 [|y|]_原 [∣y∣]原=0.1011
这一部分图片和文字较难理清,建议观看视频王道计算机考研 计算机组成原理 原码的乘法运算
在正式进行乘法之前,ACC置0
当前位=1,则ACC加上被乘数;当前位=0,则ACC加上0
当前位=1 00000+01101=01101
相加后的结果被放入ACC中 (ACC)+(X)->ACC
然后让ACC和MQ统一进行逻辑右移一位,ACC的最低位会移到MQ的最高位。高位补0
MQ之前的最低位被移出了寄存器,其实就是丢弃了。这是因为乘数的最低位之前已经用过了,之后肯定用不到了。
当前位=1 00110+01101=10011
(ACC)+(X)->ACC ACC的结果更新为10011
ACC和MQ统一逻辑右移一位
当前位=0 01001+00000=01001
(ACC)+(X)->ACC ACC的结果更新为01001
ACC和MQ统一逻辑右移一位
…(重复这个过程)
重复n次后,MQ的最后一位为0,这个0不参与位积的运算,因为这个0是乘数的符号位。
在数值位有n位的情况下,只需要重复n次,先加法再移位,就可以得到最后的结果。
最后处理符号位即可。
补码一位乘法
手算模拟
原码的除法运算
除法运算的思想
手算除法(十进制)
每一步商的数字和除数相乘的乘积要尽可能地接近当前的余数,但是又不超过当前的余数。
手算除法(二进制)
在二进制除法中,每一位的商只有可能取0或者1
原码除法:恢复余数法
观看此视频以获得最佳体验王道计算机考研 计算机组成原理
设机器字长为5位(含1位符号位,n=4),x=0.1011,y=0.1101,采用原码恢复余数法求x/y
符号单独处理:符号位= x s x_s xs ⊕ \oplus ⊕ y s y_s ys 数值位取绝对值进行除法计算
|x|=0.1011 |y|=0.1101 [ ∣ y ∣ ] 补 [|y|]_补 [∣y∣]补=0.1101 [ − ∣ y ∣ ] 补 [-|y|]_补 [−∣y∣]补=1.0011
ACC里存储被除数的值 01011,通用寄存器里存储除数的值 01101,MQ寄存器里存储商,在最开始时要将MQ全部置为0
在手算除法时,每一位商取0或者1是通过判断当前余数和除数的大小确定的。
对于运算器来说,其实就是判断此时ACC里保存的数和通用寄存器里保存的数哪个更大。计算机很傻,会先默认商1,如果搞错了再改为商0,并“恢复余数”。
当前ACC里的值为 01011,通用寄存器里的值为 01101,MQ里的值为 00000
默认上商1
余数为:(ACC)-(除数)->ACC 即 (ACC)+ [ − ∣ y ∣ ] 补 [-|y|]_补 [−∣y∣]补->ACC
01011+10011=11110
当前ACC里的值为 11110,通用寄存器里的值为 01101,MQ里的值为 00001
相减结果是个负数,说明应该商0
同时,应该把ACC里的数值恢复成原样,即恢复成原有的余数
之前减了一次除数,想要恢复原样,就加上一次除数
(ACC)+ [ ∣ y ∣ ] 补 [|y|]_补 [∣y∣]补->ACC
11110+01101=01011
当前ACC里的值为 01011,通用寄存器里的值为 01101,MQ里的值为 00000
当我们确定下一位的商时,需要把余数和下一位的商乘以除数得到的结果进行错位相减,即去掉首部的0,并在末位补上一个0
用硬件实现为:把ACC和MQ里的内容统一逻辑左移一位,ACC最高位丢弃,MQ低位补0
当前ACC里的值为 10110,通用寄存器里的值为 01101,MQ里的值为 00000
默认上商1
余数为:(ACC)+ [ − ∣ y ∣ ] 补 [-|y|]_补 [−∣y∣]补->ACC
10110+10011=01001
当前ACC里的值为 01001,通用寄存器里的值为 01101,MQ里的值为 00001
相减结果是个正数,上商1是正确的
把ACC和MQ里的内容统一逻辑左移一位,ACC最高位丢弃,MQ低位补0
当前ACC里的值为 10010,通用寄存器里的值为 01101,MQ里的值为 00010
…(重复这个过程)
由于机器字长为5位,最后我们得到5位商就结束了
由于是定点数,小数点位置默认确定。最后处理符号位。
原码除法:加减交替法(不恢复余数)
能否不恢复余数?
当我们得到一个负的余数a时,我们需要让余数加上除数的绝对值b来恢复余数,现在得到a+b。
我们会把a+b逻辑左移一位,逻辑左移一位相当于乘以2,得到 (a+b)×2=2a+2b
基于2a+2b,我们会再减掉除数,也就是减b,得到2a+b
也就是说,当我们得到的余数为负,需要恢复余数时,我们中间做的一系列过程来得到确定下一位商所需要的余数,总共可以合并为2a+b
即余数为负时,左移一位,再加上除数
补码除法运算
C语言中的强制类型转换
C语言中定点整数是用补码存储的。
无符号数与有符号数:不改变数据内容,改变解释方式。
长整数变短整数:高位截断,保留低位。
短整数变长整数:符号扩展。