[计算机组成原理] 02 数据的表示和运算(2)

[计算机组成原理] 02 数据的表示和运算(2)

定点数的表示

定点数:小数点的位置固定 eg: 996.007 ——常规计数

浮点数:小数点的位置不固定 eg: 9.96007* 1 0 2 10^2 102 ——科学计数法

image-20211216091448206

无符号数的表示

无符号数:整个机器字长的全部二进制位均为数值位,没有符号位,相当于数的绝对值。

image-20211216091819246

无符号数表示范围的求解:

设8位无符号数的最大值1111 1111为x,x+1= 2 8 2^8 28,所以 x= 2 8 2^8 28-1

通常只有无符号整数,而没有无符号小数。

有符号数的定点表示

image-20211216092338880

原码

原码:用尾数表示真值的绝对值,符号位“0/1”对应“正/负”

image-20211216093043729

隐含小数点之前的一个位置的位权是 2 0 2^0 20,隐含小数点之后的一个位置的位权是 2 − 1 2^{-1} 21

image-20211216093842139

真值0有+0和-0两种形式。

原码小数表示范围的求解:

2 − 1 2^{-1} 21+ 2 − 2 2^{-2} 22+ 2 − 3 2^{-3} 23+…+ 2 − n 2^{-n} 2n=1- 2 − n 2^{-n} 2n

反码

反码:若符号位为0,则反码与原码相同

若符号位为1,则数值位全部按位取反

image-20211216100431057

反码只是原码转变为补码的一个中间状态,实际中并没有什么用处。

补码

补码:正数的补码=原码

​ 负数的补码=反码末位+1(要考虑进位)

image-20211216101438408

将负数的补码转回原码的方法相同:尾数取反,末位+1

移码

移码:补码的基础上将符号位取反。注意:移码只能用于表示整数

image-20211216102020932

移码的特性保证了可以用计算机硬件很方便地实现两个移码之间的大小对比。

比较两个移码大小可以从最高位的bit开始,依次往后对比,谁先出现1谁就是更大的;如果都出现1,就继续向后对比。

在之后学习的浮点数中,会大量使用移码。

image-20211216102501811

练习

image-20211216104213454

回顾复习

image-20211216104536834

原码补码移码的作用

上面我们只是介绍了如何求原码补码移码,这一节我们来看它们的作用。

image-20211216204941714

计算机硬件对原码进行加减运算时,必须考虑符号位。当符号位为1时,要将加法转换成两个正数的减法来做。

减法的硬件实现困难。同时设计加法和减法,会使得硬件的成本和复杂度增加。

那么,能否用加法代替减法?

image-20211216205208405

image-20211216210012334

通过上面模运算的性质可以看出,是可以用加法来等价代替减法的。

我们假设计算机的机器字长为8 bit,表示范围为0 ~ 2 8 2^8 28-1。当运算超过这个范围时,计算机只会保留最低的八位,就相当于mod 2 8 2^8 28

image-20211216210814076

补码的作用:使用补码可以将减法操作转变为等价的加法,ALU中无需集成减法器。执行加法操作时,符号位一起参与运算。

移码的作用见上一小节。

移位运算

算术移位

image-20211216225603348

移位:通过改变各个数码位和小数点的相对位置,从而改变各数码位的位权。可用移位运算实现乘法、除法。

原码的算术移位

image-20220112192845761

右移:高位补0,低位舍弃。若舍弃的位=0,则相当于÷2;若舍弃的位≠0,则会丢失精度。

左移:低位补0,高位舍弃。若舍弃的位=0,则相当于×2;若舍弃的位≠0,则会出现严重误差。

定点整数和定点小数的原码移位运算是相同的。

反码的算术移位

image-20220112193256688

补码的算术移位

image-20220112193547743

只要遵循上面的规定,无论使用的是什么码,左移就相当于×2,右移就相当于÷2

由于位数有限,因此有时候无法用算术移位精确地等效乘除法。

算术移位的应用举例

image-20220112193945555

逻辑移位

image-20220112194053796

逻辑移位的应用举例

image-20220112195135890

循环移位

循环左移: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

把数值位的最高位放到进位位,原本的进位位补充出现的空位。

image-20220112195952212

加减运算和溢出判断

原码的加减运算

image-20220112230649824

原码的加减运算逻辑太复杂,用硬件实现太难了。

所以我们用补码来实现加减运算。

补码的加减运算

image-20220112231301473

溢出判断

image-20220112231706139

方法1

image-20220112232416327

A s A_s As表示被加数的正负号, B s B_s Bs表示加数的正负号, S s S_s Ss表示最终运算结果的正负号。

方法2

image-20220112232752200

只要发生了溢出,符号位的进位 C S C_S CS和最高数值位的进位 C 1 C_1 C1肯定是不同的。用异或运算来判断是否不同。

方法3

image-20220112233811734

发生溢出的时候,其实是说明给定的机器字长位数不够表示那么大的范围。

如何表示更大范围的数,从而避免溢出呢?

image-20220112234643365

原码的乘法运算

乘法运算的实现思想

手算乘法(十进制)

image-20220113204037722

手算乘法(二进制)

image-20220113205120846

二进制的原码乘法实现起来要比十进制还要方便,因为二进制的乘数每一位只有可能出现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

这一部分图片和文字较难理清,建议观看视频王道计算机考研 计算机组成原理 原码的乘法运算

image-20220113212623392

在正式进行乘法之前,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次,先加法再移位,就可以得到最后的结果。

最后处理符号位即可。

image-20220113213135404

补码一位乘法

image-20220115164341655

手算模拟

image-20220115164801308

原码的除法运算

除法运算的思想

手算除法(十进制)

image-20220115182205274

每一步商的数字和除数相乘的乘积要尽可能地接近当前的余数,但是又不超过当前的余数。

手算除法(二进制)

image-20220115185319328

在二进制除法中,每一位的商只有可能取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,并“恢复余数”。

image-20220115192627848

当前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位商就结束了

由于是定点数,小数点位置默认确定。最后处理符号位。

image-20220115193114933

原码除法:加减交替法(不恢复余数)

能否不恢复余数?

image-20220115194022665

当我们得到一个负的余数a时,我们需要让余数加上除数的绝对值b来恢复余数,现在得到a+b。

我们会把a+b逻辑左移一位,逻辑左移一位相当于乘以2,得到 (a+b)×2=2a+2b

基于2a+2b,我们会再减掉除数,也就是减b,得到2a+b

也就是说,当我们得到的余数为负,需要恢复余数时,我们中间做的一系列过程来得到确定下一位商所需要的余数,总共可以合并为2a+b

余数为负时,左移一位,再加上除数

image-20220115194424920

image-20220115194654999

补码除法运算

image-20220115204933688

C语言中的强制类型转换

C语言中定点整数是用补码存储的。

image-20220115205959887

无符号数与有符号数:不改变数据内容,改变解释方式。

长整数变短整数:高位截断,保留低位。

短整数变长整数:符号扩展。

数据的存储和排列

大小端模式

image-20220115233426748

边界对齐

image-20220115234053726

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值