| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 数据结构与算法 -> C语言丨小 学 数 学(二):高精度乘法 -> 正文阅读 |
|
[数据结构与算法]C语言丨小 学 数 学(二):高精度乘法 |
先从一个问题说起:编程计算并输出1~40之间的所有数的阶乘。 乍一看题目,似乎很简单:在初学循环语句的时候,累乘问题是一个较基本的问题,实现其功能的代码如下:
运行一下程序,我们就会发现情况和我们想象的不太一样: 啊这……似乎从十几的阶乘开始,就出现了一些不可描述的错误。为什么会这样呢? 其实这正是因为long类型变量有他存储范围的上限,当超过这个范围时,数值便会溢出,导致发生错误。那么有没有方法可以解决这个问题呢?我们就需要用到数组:用一个包含50个元素的数组存储一个大数,每个数组元素存储大数中的一位数字。 而两个数据的乘法则需要模拟乘法竖式的运算,忘记了竖式运算方法的朋友们可以自行翻阅《人民教育出版社数学四年级上册》第四章:三位数乘两位数[2]哦~(不会吧不会吧不会真的有人不如小学生吧(狗头)) 先来复习一下:乘法的竖式运算分为三步:(1)位数多的数的每一位和位数少的数的个位相乘,位数多的数的每一位和位数少的数的十位相乘,……,位数多的数的每一位和位数少的数的最高位相乘;(2)按由乘低位到乘高位的以此往前一位写每一次乘得的结果;(3)所有结果相加,得到最终结果。其中,后位向前进位的步骤蕴含在第一步和第三步中。 乍一听是不是很复杂?其实原理大家都懂,只是描述的方式不同。但其实在乘法的竖式运算的步骤是经过人为把乘法运算简化的,其中第二步就是一个简化的结果,涉及到一些运算技巧。那我们如果要让计算机实现第二步,就显得比较困难。如果位数少的数只有一两位还好办,但如果位数少的数的位数也比较多,这时第二步的处理就会显得尤为复杂。 这时候,我们就要回到多位数乘法的本质:多位数乘法实质上是一个多位数的逐位与另一个多位数相乘,并使后位向前进位,最终得到一个新的多位数。而进位的原则就是让每一位的数都处于0~9之间。 我们先把问题拆解:首先我们要有一个存储大数的数组,于是我们定义一个常量SIZE为51,并定义数组int data[SIZE] = {0};。之所以要定义一个长度为51的数组,是为了在后续判断大数位数是否大于50位,若大于50,数组溢出,则提示错误信息,这就需要另外定义一个变量int index = 1;来记录数组元素个数,表示阶乘值的位数;而把数组初始化为0,是为了避免数组未初始化而产生随机值导致错误。而此后应让data[1] = 1;,准备计算阶乘。 接下来我们要定义一个变量int n;,n的值由用户输入,含义为准备计算的阶乘中的最大数。为避免用户输入非法数据,我们需要检测用户输入数据的合法性:
具体原理可参见我之前的文章C语言丨检测用户键盘输入数据的合法性,这里不再赘述。 得到了准备计算的阶乘中的最大数后,我们就可以开始使用循环,计算1~n之间所有数的阶乘值了:
让第二重循环的执行条件为j<=index而非j<SIZE的原因是index记录的是数组元素的个数,也即该储存的大数的位数,当j>index时,data[j]全部为0,而0乘任何数都为0,就没必要进行多余的计算。 那么使用了这样一个循环条件,必然要在每一次计算中改变index的值。根据我们为index赋值的含义,只要数组中的最高位元素大于等于10,即data[index] >= 10,则意味着该数的位数要大于index,此时则需要执行index++;操作。通过如下代码可实现:
其实在处理最高位时,我们已经用到了进位的方法,也即while循环中的前两行,这是进位的核心代码。把index换为k,让k遍历1~index-1的所有值,即可将除最高位之前所有位进位。此段代码应放在处理最高位的前面,因为只有先处理了最高位之前的所有位,才有所谓的“最高位”。 因此我们可以整理得计算阶乘的代码如下:
到此为止,我们已经完成了阶乘计算的操作了,剩下要做的的只有打印阶乘值。这时我们之前定义的SIZE=51以及index就起作用了:若index>50,则表示数组溢出,提示错误信息。
此处,index的作用再一次体现了出来:我们无需处理最高位前的所有0元素,只需从最高位开始打印阶乘值的每一位数即可。 到此,我们就完成了整个题目的代码编写了。让我们来回顾一下整个历程:逐位相乘->后位向前进位->处理最高位->输出阶乘值。下面给出完整的代码:
[3] 和高精度加法一样,代码的核心就是人工模拟计算的过程,其中包括加/乘法和进位,只要能解决这两个问题,一切高精度算法都可以迎刃而解。 参考文献:[1]百度百科. [2]数学四年级上册,人民教育出版社,P48-56. [3]苏小红 王甜甜 赵玲玲 范江波 车万翔 等编著 王宇颖 主审,C语言程序设计学习指导(第4版),高等教育出版社,P126-127. |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/26 14:48:42- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |