1.写在前面

前面我们已经学了各种指令,我们都知道计算机的主要的工作就是收集数据,采集数据,然后处理数据,最后输出数据。但是我们还是不知道数据在计算机中如何进行计算和处理的。

2.前言

计算机的字由位组成,因此,字可以被表示为二进制数字。整数可以用十进制或二进制形式表示,但其他常用数字又该如何表示呢?

  • 如何表示小数和其他实数?
  • 如何运算产生了一个大到无法表示的数该如何处理?
  • 这些问题中隐藏着一个谜:硬件如何真正实现乘法或除法?

3.加法和减法

加法是计算机中的必备操作。数字从右到左逐位相加,并将进位传送到左侧的下一个数字,就和手动运算一样。减法也使用加法实现:相应的操作数被简单取反后再进行加法操作。

硬件规模总是有一定限制的,比如字宽为64位,当运算结果超过这个限制时,就会发生溢出。那么在加法中何时会发生溢出?当不同符号的操作数相加时,不会发生溢出,因为总和一定不会大于其中任意一个操作数。因此,当正负操作数相加时不会发生溢出。

在减法中也有类似的不会发生溢出的情况,但原理相反:当操作数的符号相同时,不会发生溢出。当相同符号的操作数相减时,最终会变成相反符号的操作数相加。

如何检测?

当两个正数相加但和为负数时,说明发生了溢出。

当正数减负数并得到负数结果,或者当负数减正数且结果为正数时,减法运算发生溢出。

刚刚看到了如何在计算机中检测二进制补码操作的溢出。无符号整数通常用于表示忽略溢出的内存地址。

幸运的是,编译器可以轻松检查出使用分支指令的无符号溢出。如果总和小于加数中的任何一个,则加法溢出,而如果差大于被减数,则减法溢出。

小结

无论数的表示形式如何,计算机的有限字长意味着算术运算可能会产生过量而无法用这种固定字长表示的运算结果,即发生溢出。虽然无符号数的溢出容易检测,但无符号数通常使用自然数做地址运算,而程序通常不需要检测地址计算的溢出,所以这些溢出总被忽略。二进制补码对检测溢出提出了更大的挑战,但仍有一些软件系统需要识别溢出,因此今天所有的计算机都支持溢出检测。

注意:加法的速度取决于向高位进位的计算速度。有很多种方案可预测进位,最坏情况下进位时间是加法器位长的log2的函数。这些预期信号速度更快,因为它们依次通过的门更少,但需要更多的门来预测正确的进位。

4.乘法

首先我们回顾一下在手工计算十进制数乘法时的步骤和操作数名称。

第一个操作数称为被乘数,第二个操作数被称为乘数,最后的结果称为积。你也许还记得小学时学到的乘法法则,即每次从右到左选择乘数的一位,用这一位乘上被乘数,然后将所得到的中间结果相对于前一位的中间结果左移一位。

可以观察到,积的位数比被乘数和乘数都大得多,事实上,如果我们忽略符号位,n位被乘数和m位乘数的积是n+m位的数。也就是说,需要n+m位表示所有可能的结果。因此,像加法一样,乘法也需要处理溢出,因为我们常常想用一个64位的乘积来表示两个64位数相乘的结果。

在上面的例子中,我们把十进制数限制为0和1。因为只有两个选择,所以每一步的乘法都很简单:

  1. 如果乘数位为1,只需要将被乘数(1*被乘数)复制到适当的位置。
  2. 如果乘数为0,则将0(0*被乘数)置于适当的位置。

虽然上面十进制的例子恰巧只使用了0和1,但是二进制乘法必须只使用0和1,因此只提供了两个选择。

4.1串行版的乘法算法及其硬件实现

假设乘数位于64位乘法寄存器中,并且将128位乘积寄存器初始化为0。从上面的纸笔法示例中可以清楚地看到,我们需要在每一步计算中将被乘数左移一位,因为它可能会和之前的中的结果相加。在64步计算之后,64位被乘数会向左移动64位。因此,我们需要一个128位的被乘数寄存器,将其初始化为右半部分的64位被乘数和左半部分的零。然后该寄存器每执行一步便左移1位,将被乘数与128位的乘积寄存器中的中间结果对齐并累加到中间结果。

对于操作数的每一位都需要做的三个基本步骤。第一步中的乘数最低数(乘数第0位)决定了是否要把被乘数加到积寄存器当中。第二步中的左移起着将中间操作数左移的作用,就像手工纸笔做乘法一样。第三步中的右移给出了下次迭代要检测的乘数的下一位。这三个步骤重复64次就会得到最后的积。如果每个步骤花费一个时钟周期,那么该算法计算两个64位数相乘差不多要花费200个时钟周期。

这种算法和硬件很容易改进到每步只花费一个时钟周期。加速来源于操作的并行执行:如果乘数位是1,那么对被乘数和乘数进行移位,与此同时,把被乘数加到积上。硬件只需要保证它检测的是乘数的最右位,而且得到的是被乘数移位前的值。注意到寄存器和加法器有未使用的部分后,通常会将加法器和寄存器的位长减半以进一步优化硬件结构

4.2带符号乘法

到目前为止,我们只处理了正数乘法的情况。对于如何处理带符号乘法,最简单的方式是先把被乘数和乘数转换为正数,然后记住它们的初始符号。这样,将之前的算法迭代执行31次,符号位不参与计算。

4.3快速乘法

摩尔定律提供了非常充足的资源,从而使硬件设计人员可以实现更快的乘法硬件。通过在乘法运算开始的时候检查64个乘数位,就可以判定是否要将被乘数加上。快速乘法可以通过为每个乘数位提供一个64位的加法器来实现:一个输入是被乘数和一个乘数位相与的结果,另一个输入是上一个加法的输出。

一种简单的方法是将右侧加法器的输出连接到左侧加法器的输入端,形成一个高64位的加法器栈。另外一种方式是将这64个加法器组织成并行树。这样我们就只需要等待log2(64),即6次64位长加法的时间,而不是64次。

实际上,由于使用进位保留加法器,乘法的速度甚至比6次的加法还要快,并且因为容易将上述的设计流水化,它能够同时支持多个乘法。

4.4RISC-V中的乘法

为了产生正确带符号或无符号的128位积,RISC-V有四条指令:乘(mul),乘法去高位(mulh),无符号乘法取高位(mulhu)和有符号/无符号乘法取高位(mulhsu)。要获得整数64位积,程序员应使用mul指令。要想得到128位积的高64位,如果两个操作数都是有符号的,程序员应使用mulh指令;如果两个操作数都是无符号的,则使用mulhu指令;或者如果一个操作是有符号的而另一个是无符号的,则使用mulhsu指令。

4.5总结

乘法硬件只是进行简单的移位和相加。编译器甚至会直接使用移位指令来做2的幂的乘法。通过使用更多硬件,我们可以做并行加法,并且做的更快。

5.除法

乘法的逆操作是除法,除法操作使用相对较少且很诡异。它甚至会出现无效的计算操作:除以0。首先通过一个十进制的长除法的命名以及小学时学习的除法算法。

除法的两个源操作数分别叫做被除数和除数,除法的结果叫做商,随之产生的附带结果叫做余数。

被除数=商*除数+余数

其中余数小于除数,少数情况下会有程序使用除法指令来获取余数而忽略商。

基本除法算法试图查看可以减去一个多大的数字,从而每次得到商的一位数。我盟精心挑选的十进制例子只使用数字0和1,因此每次容易计算出除数从被除数中减去的次数:要么是0次,要么是1次。二进制数只包含0或1,因此二进制除法仅限于这两种选择,这就简化了二进制除法运算。

5.1除法算法及其硬件实现

在开始时将64位的商寄存器置0.算法的每次迭代都需要将除数右移一位,因此开始需要将除数放置到128位的除数寄存器的左半部分,并且每运算异步并将其右移1位,使之与被除数对齐,余数寄存器初始化为被除数。

与人不同,计算机没有聪明到能预先知道除数是否小于被除数。它必须现在步骤1中减去除数,这正是我们实现比较所使用的方式。如果结果是正数,则除数小于或等于被除数,所以在商中生成一位1(步骤2a)。如果结果为负,则下一步是通过将除数加回余数来恢复原始值,并在商中生成一个位0(步骤2b)除数右移,然后再次迭代。在迭代完成后,余数和商将存放在其同名的寄存器中。

这个算法及其硬件结构可以被改进得更快且更便宜。通过操作数移位和商与减法同时进行加速。该细化包括注意哪里有未使用的寄存器和将加法器和寄存器宽度减半。

5.2有符号除法

到目前为止,我们忽略了有符号数的除法。最简单的解决办法是记住除数和被除数的符号,如果符号相异,则商为负。

被除数=商*除数+余数

我们来看看正负7除以正负2的所有组合的示例。第一种情况很简单

+7\+2 商=+3 余数=+1

检查结果:

+7=3*2+(+1) = 6+1

如果改变被除数的符号,商也一定会随之改变:

-7/+2 :商 = -3

重写基本公式来计算余数:

余数 = (被除数 - 商 * 除数) = -7 - (-3 * +2) = -7 - (-6) = -1

因此:

-7 / +2 :商 = -3,余数 = -1

再次检查结果:

-7 = -3 * 2 + (-1) = -6 -1

答案不是商为-4以及余数为+1(这也适应于这个公式)的原因是伤的绝对值会根据被除数和除数的符号而改变!显然,如果

-(x/y) != (-x)/y

编程将面临一个更大的挑战。这种异常情况通过让被除数和余数保持相同符号来避免,而不管除数和商的符号如何。通过遵循相同规则来计算其他组合:

+7 / -2 :商 = -3 余数 = +1
-7 / -2 :商 = +3 余数 = -1

因此,如果源操作数的符号相反,那么正确的有符号除法算法的商为负,并让非零余数的符号与被除数的符号相匹配。

5.3快速除法

摩尔定律使用于除法硬件以及乘法运算,所以希望能够通过其硬件来加速除法。通过使用许多加法器来加速乘法,但不能对除法使用相同的方法。因为在执行下一步运算之前,需要先知道减法结果的符号,而乘法运算可以立即计算64个部分积。

5.4RISC-V中的除法

为了处理有符号的整数和无符号的整数,RISC-V有两条除法指令和两条余数指令:除(div),无符号出(divu),余数(rem)和无符号余数(remu)

5.5总结

支持乘法和除法的通用硬件允许RISC-V提供一个单独用于乘法和除法的64位寄存器。通过预测多位商再纠正错误的预测方法来加速除法。

6.写在最后

前面我们介绍完了整数的加法减法以及乘法除法,下一节我们将要介绍浮点数的计算。

计算机是如何进行计算的?(一)相关推荐

  1. 计算机组成原理考试计算题,计算机组成原理常考计算题.doc

    文档介绍: 计算机组成原理常考计算题 1. 机器数字长为8位(含1位符号位),当X= -127 (十进制)时,其对应的二进制表示, (X)原表示,(X)反表示,(X)补表示,(X)移表示分别是多少? ...

  2. 计算机组成原理(分析计算题解析)内附填空,选择,解答题答案

    目录 关于计算机组成原理的填空,选择以及解答题 1. 2. 3. 1.所以首先将整数和小数部分转化成二进制 2.移动小数点 3.得到二进制存储格式 4. 5. 6. 7. 8. 9. 计算机组成原理( ...

  3. 计算机导论在线阅读,计算思维与计算机导论.pdf

    第 36 卷 第 4 期 计 算 机 科 学 Vol . 36 No . 4 2009 年 4 月 Co mp ut er Science Ap r . 2009 计算思维与计算机导论 董荣胜 (桂林 ...

  4. 计算机思维能力培养的核心是什么,【计算机基础论文】计算机基础教学中计算思维能力培养(共6714字)...

    计算机基础教学中计算思维能力培养 摘要:自C9明确提出大学计算机基础教学的核心任务是培养学生计算思维能力后,计算思维能力培养日益受到重视.但从培养目标.培养方式.培养过程.培养效果来看,还存在诸多问题 ...

  5. 大一计算机思维知识点,大学计算机基础教学中计算思维的培养途径

    摘要:从几个侧面思考和探究在大学计算机基础教学中培养学生计算思维的途径,提出通过整合教学内容,将不同的知识点归纳为不同的知识单元:通过实验教学,提升学生运用计算思维处理问题的能力. 关键词:计算思维: ...

  6. 计算思维应用于计算机学科,【计算机教学论文】计算机教学中的计算思维培养(共2667字)...

    摘要:在中职院校内,Excel课程是一门计算机基础学科.在其教学过程中,我们应从问题出发,提出自身的解决策略,来培养学生的计算思维. 关键词:计算思维:体系:思维内涵:职业教育 一.中职院校Excel ...

  7. 计算机外设分为三类,2021年计算机外设包含什么-计算机外设有什么组成.docx

    文档介绍: 计算机外设包含什么:计算机外设有什么组成 你们知道电脑外设是什么吗?知道电脑外设包含什么吗?下面是xx搜集整理有关电脑外设包含什么的资料以供大家参考学****期望大家喜爱. 电脑外设 电脑 ...

  8. 选股器用计算机测试利润,ROE+市盈率选股 上周使用计算公式:总得分=营业净利润率+资产负债率+市盈率,来筛选股票。 因为笔者不会计算机编程,在计算历年平均值的时候... - 雪球...

    来源:雪球App,作者: 小叮当当当,(https://xueqiu.com/6206539641/116662823) 上周使用计算公式:总得分=营业净利润率+资产负债率+市盈率,来筛选股票. 因为 ...

  9. 家用计算机1秒钟能计算,用计算器计算

    <用计算器计算>由会员分享,可在线阅读,更多相关<用计算器计算(38页珍藏版)>请在人人文库网上搜索. 1.用计算器计算,王叔叔的采购清单:,李阿姨的采购清单:,显示屏,退出, ...

  10. 二进制在线计算机,计算机进制转换计算

    <计算机进制转换计算>由会员分享,可在线阅读,更多相关<计算机进制转换计算(8页珍藏版)>请在人人文库网上搜索. 1.各种进制转换一.进制的概念在计算机语言中常用的进制有二进制 ...

最新文章

  1. Keras运行速度越来越慢的问题
  2. C语言网络编程:close或者shutdown断开通信连接
  3. PHP返回数据json数据样式要求是对象{},而不是[]
  4. apache-tomcat-7.0.54安装
  5. python数据分析天气预报论文_用python+sklearn(机器学习)实现天气预报数据 模型和使用...
  6. 卸载cuda_NVIDIA驱动和CUDA安装
  7. 【linux】RedHat 安装 gcc、g++
  8. 轻松搞定JSONP跨域请求
  9. jquery检测input变化_jquery 监控input输入框值得变化
  10. 使用java理解程序逻辑 第十二章_Java多线程中锁的理解与使用(二)
  11. 讯飞输入法将深度神经网络DNN技术应用于语音识别达到业界领先水平
  12. Qt使用Qtxlsx读写xlsx文件
  13. vue中修改了数据但视图无法更新的情况
  14. EDK2 UDK2018的环境搭建
  15. PS批量处理_将图片批量转为jpg
  16. 怎样找到优质的APP推广渠道
  17. Python 实现三维建模工具(上)
  18. STM32G030 低功耗
  19. 广东省推出居民身份电子凭证,忘带身份证也能住酒店了
  20. 故障分析 | 数据库表空间被 rm 后,怎么处理

热门文章

  1. local_rank,rank,node等理解
  2. 【ZOJ 1151】Word Reversal 题解(字符串+模拟)
  3. matlab中reshape和repmat使用方法
  4. 【2021最新版】Spring面试题总结(131道题含答案解析)
  5. 计算机毕业设计springboot+vue基本安卓/微信小程序的驾校考试预约系统 uniapp
  6. 什么是 RBAC 模型?
  7. linux comm命令_在Linux中使用Comm命令比较文件
  8. 标准DH坐标系,改进DH坐标系转换矩阵matlab函数代码1.0
  9. 未雨绸缪,08年末时尚数码礼品导购
  10. 3 5mm接头(耳机头)到RCA接头(莲花头)转接线制作