计算机组成原理<四>——数据的表示和运算(下)

                         未来属于那些相信梦想并愿意为之付诸行动的人

                                               


                                                           满满的 

定点数的表示与运算

定点数的表示

定点数的运算

移位运算

章节回顾 

加减运算

章节回顾 

乘法运算

除法运算

C语言中的整数类型及类型转换

数据的存储和排列

浮点数的表示与运算 

浮点数的表示

浮点数标准IEEE754

浮点数的运算

算术逻辑单元(ALU)

电路的基本原理,加法器设计

加法器,ALU的改进


定点数的表示与运算

定点数的表示

无符号数与有符号数

1)无符号数

指整个机器字长的全部二进制位均为数值位,没有符号位,相当于数的绝对值.若机器字长为8位,则数的表示范围为0——2^8-1,即:0-255

注:通常只有无符号整数,而没有无符号小数.

2)有符号数

机器数的定点表示

定点小数

定点小数是纯小数,约定小数点位置在符号位之后,有效数值部分最高位之前.若数据X的形式为X=x0x1x2x3....xn(其中x0为符号位,x1-xn是数值的有效部分,也称尾数,为最高有效位),则在计算机中的表示形式如图:(机器字长为n+1位)

当x0=0,x1-xn均为1时,X为其所能表示的最大正数,真值为1-2^-n;

当x0=1,x1-xn均为1时,X为其(原码)所能表示的最小负数,真值等于-(1-2^-n);

 定点整数

定点整数是纯整数,约定小数点位置在有效数值部分最低位之后.若数据X的形式为X=x0x1x2....xn(其中x0为符号位,x1-xn是尾数,xn为最低有效位),则在计算机中的表示形式如图2.5所示(设机器字长n+1位).

当x0=0,x1-xn均为1时,X为其所能表示的最大正数,真值为2^n-1

当x0=1,x1-xn均为1时,X为其(原码)所能表示的最小负数,真值等于-(2^n-1);

原码,反码,补码,移码 

原码

用机器数的最高位表示该数的符号,其余的各位表示数的绝对值.原码的定义如下:

注意:真值零的原码表示有正零和负零两种形式,即[+0]原=00000和[-0]=10000。

反码

反码通常用来作为由原码求补码或由补码求原码的中间过渡。

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

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

 补码

正数的补码=原码

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

 移码

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

 注:移码全0时,对应真值的最小值-2^n;移码全1时,对应真值的最大值为2^n-1;

      移码保持了数据原有的大小顺序,移码大真值就大,移码小真值就小;

知识回顾

定点数的运算

移位运算

原码的算术移位

原码的算术移位——符号位保持不变,仅对数值位进行移位.

右移:高位补0,低位舍弃.若舍弃的位=0,则相当于/2:若舍弃的位不等于0,则会丢失精度 

 左移:低位补0,高位舍弃,若舍弃的位=0,则相当于/2,若舍弃的位不等于0,则会出现严重误差

反码的算术移位

反码的算术移位——正数的反码和原码相同,因此对正数反码的移位运算也和原码相同

右移:高位补0,低位舍弃.

左移:低位补0,高位舍弃

反码的算术移位——负数的反码数值位与原码相反,因此负数反码的移位运算规则如下,

右移:高位补1,低位舍弃

左移:低位补1,高位舍弃

补码的算术移位 

补码的算数移位——正数的补码与原码相同,因此对正数补码的移位运算也和原码相同

右移:高位补0,低位舍弃

左移:低位补0,高位舍弃

补码的算数移位——负数补码=反码末位+1

导致反码最右边几个连续的1都因进位而变为0,直到进位碰到第一个0为止.

规律——负数补码中,最右边的1及其右边同原码.最右边的1的左边同反码.

负数补码的算数移位规则如下:

右移(同反码):高位补1,低位舍弃

左移(同原码):低位补0,高位舍弃

逻辑移位 

逻辑移位将操作数视为无符号数,移位规则:逻辑左移时,高位移丢,低位添0;逻辑右移时,低位移丢,高位添0

注意:逻辑移位不管是左移还是右移,都添0

循环移位 

循环移位分为带进位标志位CF的循环移位(大循环)和不带进位标志位的循环移位(小循环),过程如图2.7所示

循环移位的主要特点是,移出的数位又被移入数据中,而是否带进位则要看是否将进位标志位加入循环位移。例如.带进位位的循环左移就是数据位连同进位标志位一起左移,数据的最高位移入进位标志位CF,而进位位则依次移入数据的最低位

章节回顾 

加减运算

原码加减运算

 这样用减法器和加法器可以求出结果,加法器设计起来简单,不过减法器设计起来就很复杂了而且成本也高。那么我们能不能想一个方法,只用加法器来完成这个过程?

加法代替减法

我们举个例子,假如现在10点,我们如何将其调到7点?第一种方法就是逆时针调三格,10-3就可以了,第二种方法就是顺时针调九个,(10+9)%12,这就相当于求余数了

模运算性质:

带余除法——设x,m属于Z,m>0则存在唯一决定的整数q和r,使得:

x=qm+r  0<=r<m

 说明-3,9,21,33,-15这些数都是等价的

想用加法代替减法。就可以用9代替-3,这两者又是互补的

所以:模-a的绝对值=a的补数(12-3=9)

在机器字长为8bit位上,可以看成是模2^8,数都映射到0-2^8-1上.:

计算机只有八个比特字长,硬件会天然的帮我们模2^8,最高位1会被处理掉,结果就是0了

补码——让减法操作转变为加法操作,节省硬件成本.

这里其实就是求该数的补码(模-a的绝对值=a的补数)

 

补码加减运算 

溢出判断

 计算机如何进行溢出判断?

  

符号扩展


在一定程度上避免溢出

章节回顾 

乘法运算

原码的乘法运算

我们小学的时候算两个数相乘是怎么计算的?现在我们先来模拟一下手算乘法:

 实际上就是:

0.1011(乘数)=1*2^-1+0*2^-2+1*2^-3+1*2^-4

0.1101(被乘数)=1101*2^-4

0.1101*0.1011=(1101*1*2^-8)+(1101*2^-7)+(1101*2^-6)+(1101*2^-5)

用移位就可以实现

现在我们要考虑如何用机器实现:

  • 实际数字有正负号,符号位如何处理?
  • 乘积位数扩大一倍,该如何处理?
  • 4个位积都要保存下来最后统一相加?

我们带着这几个问题,接着往下面走:

先看一下这个图,后面会用到

首先看一道例题:

ACC全部初始化为0,看MQ的最右边的第一位是1/0,当前位为1则ACC加上被乘数,为0则ACC加上0

 丢弃的那一位就不用看了,直接看方格里的,MQ的最右边第一位还是1,则ACC加上被乘数

00110+01101=10011,然后再逻辑右移一位,ACC高位补0

 重复上面的过程,MQ的右边第一位是0,则ACC加上0,再逻辑右移一位

MQ的右边是1,则ACC+X;00100+01101=10001,再逻辑右移一位

 MQ最右边只剩下一个0了,但这个0不需要参与运算,因为他是乘数的符号位

还需要根据异或的结果来修改这个符号位:这里显示是-1

最后结果就是:1.10001111

到这里ACC为什么叫乘积高位,MQ为什么叫乘积低位相信大家也都理解了

手算模拟

  • 乘数的符号位不参与运算,可以省略
  • 原码一位乘可以只用单符号位

 总结:符号位通过异或确定,数值部分通过被乘数和乘数绝对值的n论加法,移位完成,根据当前乘数中参与运算的位确定(ACC)加什么。若当前运算位=1,则(ACC)+[|x|]原;若=0,则(ACC)+0;每轮加法后ACC,MQ的内容统一逻辑右移

补码的乘法运算 

 首先来看下原码和补码乘法的区别

那么上面说到补码要借助辅助位,那就让我们来看看补码的运算器是怎么样的

 手算模拟

除法运算

原码的除法运算

原码的除法运算有恢复余数法和不恢复余数法(加减交替法),这里主要介绍加减交替法

手算除法

如何把这种手算的思想,用手算来实现?

跟上面乘法一样,符号位用异或单独处理,数值位取绝对值进行除法计算

恢复余数法: (机器)

计算机很傻,会先默认上商1,如果搞错了再改上商0,并恢复余数

默认上商1,用被除数减去除数来判断是否商1是否正确,

ACC-除数转换成:

ACC+[-|y|]补->ACC:01011+10011=11110

 当机器检测出ACC的首位是1,也就是负数,发现错误了,应该商0,需要恢复余数,这也就是这个名字的由来

恢复余数:ACC+[|y|补]->ACC :11110+01101=01011

这时需要ACC和MQ中内容逻辑左移(符合手算除法),低位补0

下面就和前面一样,需要先商1,然后相减判断ACC首位是否为1,为1则进行恢复余数,再进行逻辑左移,不为1,则不需要恢复余数,直接逻辑左移就行了.这里就不一一展开了,直接给出最后结果,大家可以去试试

 恢复余数法(手算)

 

每次我们都商1,然后恢复余数,这样显示是很麻烦的,那我们能不能减少操作,不恢复余数囊?

我们接着往下看:

根据上面的分析,当余数为负数时,我们不必要进行恢复余数,上图就是它从a变成了2*a-b;也就是向左移一位然后加上|除数| 。这样我们就引出了加减交替法:

加减交替法:

补码的除法运算(加减交替法)

 补码一位除法的特点是,符号位与数值位一起参加运算,商符自然形成.除法第一步根据被除数和除数的符号决定是做加法还是减法;上商的原则根据余数和除数的符号位共同决定,同号上商"1",异号上商"0";最后一步商恒置"1"。

加减交替法的规则如下:

  • 符号位参加运算,除数与被除数均用补码表示,商和余数也用补码表示
  • 若被除数与除数同号,则被除数减去除数;若被除数与除数异号,则被除数加上除数
  • 若余数与除数同号,则商上1,余数左移一位减去除数;若余数与除数异号,则商上0,余数左移一位加上除数
  • 重复执行第3步操作n次
  • 若对商的精度没有特殊要求,则一般采用"末位恒置为1"法

C语言中的整数类型及类型转换

有符号和无符号的数的转换

我们来看这一段程序

int main()
{
 short x=-4321;
 unsigned short y=(unsigned short)x;
 printf("x=%d,y=%u",x,y);
 return 0;
}

 有符号数x是一个负数,而无符号数y的表示范围显然

不包括x的值,读者可以自己猜想一下这段程序的运行结果,再比较下面给出的运行结果

x=-4321,y=61215;

这样看没有一点关系,但将这两个数化为二进制表示时,我们就会发现其中的规律,如表2.5所示

观察可知,将short int 强制转换为unsigned short只改变数值,而两个变量对应的每位都是一样的。通过这个例子就知道,强制类型转换的结果保持位值不变,仅改变了解释这些位的方式

不同字长整数之间的转换 

长整型转换为短整型

int main()
{
 int x=165537,u=-34991;
 short y=(short)x,v=(short)u;
 printf("x=%d,y=%d\n",x,y);
 printf("u=%d.v=%d\n",u,v);
}

结果:

x=165537,y=-31071

u=-34991,v=30545

十六进制表示为:x,y,u,v:0x000286a1,0x86a1,0xffff7751,0x7751,得出结论:

当大字长变量向小字长变量强制类型转换时,系统把多余的高位字长部分直接截断,低位直接赋值,因此也是一种保持位值得处理方法.

短整型变长整型

这里就不举例子了,直接说结果:

当这个数为负数,就在这个数的符号位和原有的数值位之间添1

当这个数为正数,就在这个数的符号位和原有的数值位之间添0

数据的存储和排列

数据的"大端方式"和"小端方式”存储

通常用最低有效字节(LSB)和最高有效字节(MSB)来分别表示数的低位和高位。例如,在32位计算机中,一个int型变量i的机器数位01 23 45 65H,其最高有效字节MSB=01H,最低有效字节LSB=67H

大端方式:就是将最高有效字节存放在前面;

小端方式:就是将最低有效字节存放在前面; 

浮点数的表示与运算 

浮点数的表示

定点数的局限性

我的财富:3540;2B定点整数short就可以表示

马云的财富:12345679....4B定点整数int就可以表示

如果换一种货币:1人民币=100000000000津巴布韦币用long型也表示不了

定点数表示的范围是很有限的,但我们又不能无限的增加长度

这就引出了浮点数

从科学计数法理解浮点数

普通计数法:+302657264576

科学计数法:+3.026*10^11=+11+3.026

阶码反映浮点数的表示范围及小数点的实际位置,

尾数M的数值部分的位数n反映了浮点数的精度

浮点数的表示

阶码:常用补码或移码表示的定点整数

尾数:常用原码或补码表示的定点小数

类比十进制:+302657264526=+3.026*10^11;

可以记位:+11+3.026

浮点数的真值:r^E*M;阶码的底一般为2

如果采用8比特存取空间:

 这样b的最后一个数字就被舍弃掉了,这样表示的精度就降低了,那我们有没有方法让其不损失精度囊?

浮点数尾数的规格化

举个例子:+302657264526

可记为:+11+3.026

也可记为:+14+0.003(尾数的最高位是无效值,造成精度损失)

那么上面的那个b=2^2*(+0.01001)=2^1*(+0.10010)

规格化浮点数:规定尾数的最高数值位必须是一个有效值

左规:当浮点数运算的结果位非规格化时要进行规格化处理,将尾数算数左移一位,阶码减1

右规:当浮点数运算的结果尾数出现溢出(双符号位为01或10)时,将尾数算数右移一位,阶码加1

例:a=010;00.1100,b=010;00.1000,求a+b

a=2^2*00.1100,b=2^2*00.1000

a+b=2^2*00.1100+2^2*00.1000

      =2^2*(00.1100+00.1000)

      =2^2*01.0100(发生了溢出)

右规=2^3*00.1010

注意:采用"双符号位",当溢出发生时,可以挽救。更高的符号位是正确的符号位

规格化浮点数的特点

1.用原码表示的尾数进行规格化:

正数为0.1*.....的形式,其最大值表示为0.11...1;最小值表示为0.10...0;

尾数的表示范围为1/2<=M<=(1-2^-n);

负数为1.1*....的形式,其最大值表示为1.10...0;最小值表示为1.11...1;

尾数的表示范围为-(1-2^-n)<=M<=-1/2;

2.用补码表示的尾数进行规格化:

正数为0.1*.....的形式,其最大值表示为0.11...1;最小值表示为0.10...0;

尾数的表示范围为1/2<=M<=(1-2^-n);

负数为1.0*...的形式,其最大值表示为1.01...1;最小值表示为1.00...0;

尾数表示范围:-1<=M<=-(1/2+2^-n);

浮点数标准IEEE754

移码

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

移码的定义:移码=真值+偏置值

此处8位移码的偏置=128D=1000 000B,即2^n-1

偏置值一般取2^n-1,此时移码=补码符号位取反

真值-127=-1111111B

移码=-1111111+10000000=0000 0001

真值-3=-11B

移码=-11+10000000=0111 1101

偏置值可以取其他值

令偏置值=127D=0111 1111B,即2^n-1 -1;

真值 -128=1000 0000B

移码=-1000 0000+0111 1111=1111 1111

IEEE 754标准

 例题:

浮点数的运算

浮点数加减运算步骤:      9.85211*10^12+9.96007*10^10

1.对阶;                            9.85211*10^12+0.0996007*10^12

思考为什么是小阶向大阶靠齐?将9.96化成0.0996而不是9.85转换成985?因为这样计算机内部这样处理很简单,方便对尾数进行处理

2.尾数加减;                     9.951707*10^12   

3.规格化;                         如果尾数加减出现类似0.0099517*10^12时,需要左规;如果尾数加减出现类似99.517107*10^12时,需要右规

4.舍入;                     若规定只能保证6为有效尾数,则

                                9.9517107*10^12->9.95171*10^12   (多余的直接砍掉)

                                或者,9.9517107*10^12->9.95172*10^12(若砍掉部分非0,则入1)

                                或者,也可以采用四舍五入的原则,当舍弃位>=5时,高位入1                   

5.判溢出                  若规定阶码不能超过两位,则运算后阶码超出范围,则溢出                                                        如:9.85211*10^99+9.96007*10^99=19.81218*10^99

                                规格化并用四舍五入的原则保留6位尾数,得1.98122*10^100

                                阶码超过两位,发生溢出

 二进制浮点数的加减运算

 浮点数的加减运算——舍入

 强制类型转换

算术逻辑单元(ALU)

电路的基本原理,加法器设计

最基本的逻辑运算

 优先级:与>或:AB+CD,先算与再算或

 分配律:A(C+D)=AC+AD

 结合律:ABC=A(BC)

 结合律:A+B+C=A+(B+C)

这样设计有什么意义嘛?

Eg:实现AC+AD

根据分配律我们还可以这样设计

 本质上逻辑表达式是对电路的数学化描述,简化逻辑表达式,就是在简化电路,就是在省钱。

用门电路求偶校验位

 一位全加器

 串行加法器

 并行加法器

加法器,ALU的改进

根据前面的并行加法器可知,要算ci;就要计算AiBi+(Ai异或Bi)*Ci-1;那有没有方法去优化囊?更快的产生进位囊?

c0是一开始就知道的,这样就会减少计算成本.

并行加法器的优化

这里有点难理解,大家可以看我截的图,去b站看王道的课;

优点:各级进位信号同时形式,不需要重复计算,节省时间;

缺点:一直套娃,电路设计就会越来越复杂

为了避免这个缺点,我们四个为一组就可以了.

进行不断的套娃;

 ALU芯片的优化

  • 15
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 16
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

接受平凡 努力出众

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值