| |
|
开发:
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语言丨小 学 数 学(一):高精度加法 |
先从一个问题说起:编程从键盘输入n,然后计算并输出1+2+3+…+n的值。 这应该是每个人初学循环控制结构与循环语句时都会遇到的经典问题,最初我们接触到的代码如下:
但其实这个代码是有局限性的,它只能解决n比较小时的累加求和问题,当n很大时,计算机的精度就会下降。这是因为int型变量在内存中只占4个字节,所表示的范围仅为~,即为-2147483648~2147483647。又有人会说,那int不够用,用long int、long long int总可以吧?但是这些数据类型始终有它们的最大取值范围,当n足够大,大到无法用任何数据类型存储时,这些方法便失去了价值,此时计算机的强大功能甚至比不上一个三年级的小学生的数学水平。 那有没有什么通用的方法呢?我们以一道例题来作为例子探究: 使用一维数组实现两个正整数相加,输出它们的和。两个正整数位数最少为20位,不超过50位,注意两个加数的位数不一定相等。 其实题目给的提示已经足够多了,就是利用加法的竖式运算原理,模拟进位运算,实现两个大数相加,具体数学原理可以参见《人民教育出版社数学三年级上册》第四章:万以内的加法和减法(二)[2],这里不作展开。(看看谁是九年义务教育漏网之鱼🤪🤪) 首先,我们需要三个数组,一个数组的每一位元素分别存储一个大数的每一位数,于是我们可以先定义三个整型数组:
为什么sum需要N+1位呢?这是因为如果这两个50位的加数都是的首位都是9,那么和的首位将会进一,届时用50位的数组便无法存储下这么多的数。那为什么要全部清零呢?这是为了避免未赋值的元素为系统产生的随机值。 定义完数组之后,接下来要思考的就是,怎么样把正整数的每一位拆开,分别输入进数组num1与数组num2中?能否使用以下的方法?
如果这样的话,倘若我们输入:
会发生什么事情? 结果是num1[0]=567,num1[1]=100,这时相信我不说您也知道问题出现在哪里了,于是我们将以上代码改为:
但是这样真的就可以了吗? 并不行,因为如果第一个输入的数还没有到50位,第一个循环并不会结束,因此第二个数也会被录入到第一个数组中。 所以我们应该用getchar()代替函数scanf(),将getchar()读取到的字符减去'0'的ASCII码值,得到相应的十进制数。也即:
但现在有个很头疼的问题,就是我要如何找到这两个数的个位在哪里?相加的时候如何使个位互相对齐、十位互相对齐……?于是我们需要引入一个变量count来帮助我们计算我们输入数字的位数,并使个位与最高位交换,十位与次高位交换……直到把数翻转过来(如使12345变为54321),因为这样的话数组的第0个元素都是个位,更有利于我们算加法的时候实现对齐:
这样就没有任何问题啦~那么当我们把两个加数都录入后,就可以开始进行最核心的部分:加法计算了。
如果sum[i]>=10,就需要进位,进位的核心就是把十位取出来,加到下一位上,并把个位取出来,留在本位,但鉴于当sum[i]<10时,sum[i]/10=0(整数除法),sum[i]%10=sum[i],我们可以不用单独判断是否需要进位,于是我们有:
这么写是不是就没问题了呢?通过测试,我们发现:假如是99+99,那么num1[0]=9,num2[0]=9,sum[0]=9+9=18,进位后sum[1]=1,sum[0]=8;而当第二轮循环开始后,sum[1]=num1[1]+num2[1]=18,sum[2]=1,sum[1]=8。那是不是意味着我们最终的结果为99+99=188? 答案很明显是有问题的,问题就在于第二轮循环开始后,sum[1]原来的值被新的值覆盖了,而不是在原来的基础上再加上num1[1]与num2[1],于是我们修改代码:
那么就到了最后一步:输出我们的结果啦!由于此时sum[0]储存的是个位,而最高位位于整个数字的最后面,因此我们需要倒序输出这个数组;而由于最高位后面的数字都是0,我们想要跳过0,就需要设置一个标志变量flag,因此我们有:
OK,到此为止,我们就实现了大数加法的目的了。 大数加法的核心问题就在于如何编程模拟相加-进位的过程,只要把这个问题解决了,一切问题都能迎刃而解啦~在两数相加的时候,如果我们能巧妙利用两个加数的位数,跳过最高位之前0+0的一些繁琐的计算,还能使计算效率更高;另外在输入两个正整数的时候,出现了极多重复重复再重复的代码,如果能利用子函数包装一下,可以大大增加代码的可读性,减少代码量,大家不妨思考一下如何优化。 参考文献:[1]百度百科 [2]人民教育出版社数学三年级上册 [3]SCNU2021软工4班公众号Fourever with you. RG04.?高精度加法丨超越限制的美丽. 2021-11-15(C++) |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年1日历 | -2025/1/9 15:28:49- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |