-
2022-04-22 22:22:54
本文提供高精度加法的代码
可能不太简洁,但凑合着还行
代码自己打的
高精度加法
#include <bits/stdc++.h> using namespace std; char a1[105],b1[105]; int a[105],b[105],c[10005]; int lena,lenb,lenc,x; int main() { cin>>a1; cin>>b1; lena=strlen(a1); lenb=strlen(b1); for(int i=0;i<lena;i++) a[lena-i]=a1[i]-48; for(int i=0;i<lenb;i++) b[lenb-i]=b1[i]-48; lenc=1; x=0; while(lenc<=lena || lenc<=lenb) { c[lenc]=a[lenc]+b[lenc]+x; x=c[lenc]/10; c[lenc]%=10; lenc++; } c[lenc]=x; if(c[lenc]==0) lenc--; for(int i=lenc;i>=1;i--) //此代码是直接输出结果 cout<<c[i]; //也可以把它存到一个字符串里去 cout<<endl; return 0; }
更多相关内容 -
高精度加法参考程序,简单版程序
2022-03-27 12:30:11简单程序,如果不懂,可以参考https://blog.csdn.net/dingzhekai/article/details/119614679?spm=1001.2014.3001.5502 的文章,包懂。 -
高精度大整数加法C++实现
2020-01-06 22:12:43该资源通过C++代码实现两个大整数的相加,适用于当long long也存不下的数进行相加时使用,通过数组模拟算术加法实现,运行时只需输入两个加数,敲回车即可出结果 -
C语言-高精度加法
2014-11-13 09:41:18C语言-高精度加法,C语言程序设计实验之高精度加法 -
高精度计算--高精度加法详解
2021-08-21 22:27:49文章目录系列文章目录前言一、高精度加法分析1.1 数学的竖式加法计算1.2 数组模拟竖式计算1.3 计算步骤分析二、使用步骤2.1 代码结构2.2 读入数据并倒置:readDataAndReverse(int *arr,int &len)函数2.3 两个...文章目录
前言
利用计算机进行数值计算,有时会遇到这样的问题:有些计算要求精度高,希望计算的数的位数可达几十位甚至几百位,虽然计算机的计算精度也算较高了,但因受到硬件的限制,往往达不到实际问题所要求的精度。我们可以利用程序设计的方法去实现这样的高精度计算。计算结果超过常用的数据类型长度即可使用高精度计算。
int范围:[-231,231-1],大约是109数量级。long long范围[-263,263-1],大约是1018数量级。超过这个量级,我们就可以选择高精度计算了。
一、高精度加法分析
1.1 数学的竖式加法计算
在进行高精度加法之前,我们来回顾一下小学时我们是如何进行加法计算的。我们以一个较小的数作为例子:计算12342+432的值。
我们很容易就能写出上面这个式子,计算的时候一会习惯性的从箭头位置从右往左进行计算得到结果。但是写到程序中还是这样吗?1.2 数组模拟竖式计算
前面讲了,因为数据已经超过了常用的数据类型,存入过大的数据的时候是有问题的,所以我们在存储输入的数据的时候都是使用数组来完成,现在我们来看一下数组接受数据会发生什么情况。
这里增加了下标,我们会发现一个问题,这时候想要计算,他们的下标不是对齐的,我们不能直接直接把0号下标的两个数直接相加。我们希望他们是尾部对齐的效果。那么解决这个问题我们可以先把这两个数组进行逆序(reverse)操作,算完之后再把结果倒序输出即可。顺便加上对应的数组。下图为逆序后做的计算。1.3 计算步骤分析
根据上图,我们分析一下代码步骤。
- 创建已知和未知的变量
- 程序读取a数组和b数组,并将数组倒置(reverse)
- 使用从左往右进行累加计算,并将结果存储到ans数组中。公式:ans[i]=a[i]+b[i];
- 将结果逆序输出
二、使用步骤
2.1 代码结构
计算的位数我们设定为小于500位。在写代码的时候我们可以先把我们要做的流程利用函数的形式来表示,具体的实现,等我们想清楚之后再写,这样子写的时候思路更清晰,而且做什么事也不会写乱了。
代码如下(示例):#include <iostream> #include <string> using namespace std; // 1. 创建变量(包括三个数组、数组的大小N、三个数组的长度,t表示进位) const int N = 520; int a[N],b[N],ans[N],len_a,len_b,len_ans,t; void readDataAndReverse(int *arr,int &len); void addData(int *a,int *b,int &len_ans); void reversePrint(int *ans); int main(){ // 2. 读入数据并倒置 readDataAndReverse(a,len_a); readDataAndReverse(b,len_b); // 3. 数组做累加 addData(a,b,len_ans); // 4. 逆序输出 reversePrint(ans); return 0; } void readDataAndReverse(int *arr,int &len){ } void addData(int *a,int *b,int &len_ans){ } void reversePrint(int *ans){ }
2.2 读入数据并倒置:readDataAndReverse(int *arr,int &len)函数
代码如下(示例):
/* 函数功能:读入数据,并逆序存入数组 参数: arr:要存入数据的数组 len:对应数组的长度 返回值:null */ void readDataAndReverse(int *arr,int &len){ // 1. 由于数据量比较大,所以我们都是先读入字符串,再转存数组 string s; cin>>s; len = s.length(); // 字符串的长度,就是对应数组(a,b数组)的长度 /* i: 表示arr数组的下标,从1开始到len(不从零开始存,方便记忆) j: 表示s字符数组的下标,从结尾len开始到1 s[j]-'0': s[j]得到的是一个字符数字,这个字符数字想要转成真正的数字需要减去0,详见ASCII码表 */ for(int i=0,j=len-1;j>=0;i++,j--){ arr[i] = s[j]-'0'; } }
测试:在两个输入的函数下面添加打印数组的代码做测试,是可以的。
2.3 两个数据相加:addData(int *a,int *b,int &len_ans)函数
这里我们增加一个变量t,t表示进位数值。我们思考这么一个问题,在前面的例子中,我们对两个数字进行累加的时候并没有考虑到a[i]+b[i]>=10的情况,如果不做进位维护的话,会导致结果和预期不一样。通过下图,我们再看一下程序改如何改进:
根据上面的图片,增加的部分是进位维护程序,并且是在得到ans数组之后进行的。/* 函数功能:对两个数组进行累加 参数: a:a数组 b:b数组 len_ans:累加后的数组长度 返回值:null */ void addData(int *a,int *b,int &len_ans){ // 1、得到a和b中最长的数组长度 len_ans = len_a; if (len_a<len_b){ len_ans = len_b; } // 做累加 t=0; // 进位,默认第一次累加为零 for(int i=0;i<=len_ans;i++){ ans[i] = a[i]+b[i]+t; t=0; // 每次累加完之后归零,并不是每次都有进位 // 进位维护,如果累加之后结果大于等于10,进位变1,结果%10 if(ans[i]>=10){ t = 1; ans[i]=ans[i]%10; } } // 累加完了之后判断最后进位t是否等于1,是的话说明还有一位数,我们手动加到数组中 if(t==1){ len_ans++; ans[len_ans-1]=1; } }
输入数据做测试,需要自己在addData()后面添加打印程序。没有问题。2.4 逆序输出:reversePrint(int *ans)函数
上一部分我们已经做了输出,发现并没有问题,到这一步,我们只是需要把它倒序输出吗?也就是下面的代码。
尝试输入:00123 00123
他会输出246吗?void reversePrint(int *ans){ for(int i=len_ans-1;i>0;i--){ cout<<ans[i]; } }
2.4.1 去除前导零
可以看到,并不是我们想要的结果,因为算出来的前面还有两个0,我们称这个为前导零。所以下面我们要做的就是去除前导零
如何去除前导零呢?如上图所示,我们需要一个“指针”,当然这个并不是c++中的那个指针,这里只是表示指向那个位置的一个值,刚好这个值就是len_ans,所以用len_ans当这个“指针”就行。处理步骤按图上的来就行。void reversePrint(int *ans){ // 最后一个位置是len_ans-1,所以从ans[len_ans-1]开始判断 while(ans[len_ans-1]==0&&len_ans-1>0){ len_ans--; } // 逆序输出 for(int i=len_ans-1;i>=0;i--){ cout<<ans[i]; } }
总结
高精度加法步骤:
- 创建对应的数组变量及其他变量
- 以字符串形式读入数据并逆序存储到数组中
- 将两个数组做累加, 注意进位的维护
- 逆序输出(注意删除前导零)
完整代码
1.使用函数形式
#include <iostream> #include <string> using namespace std; // 1. 创建变量(包括三个数组、数组的大小N、三个数组的长度) const int N = 520; int a[N],b[N],ans[N],len_a,len_b,len_ans,t; void readDataAndReverse(int *arr,int &len); void addData(int *a,int *b,int &len); void reversePrint(); int main(){ // 2. 读入数据并倒置 readDataAndReverse(a,len_a); readDataAndReverse(b,len_b); // 3. 数组做累加 addData(a,b,len_ans); // 4. 逆序输出 reversePrint(); return 0; } void readDataAndReverse(int *arr,int &len){ // 1. 由于数据量比较大,所以我们都是先读入字符串,再转存数组 string s; cin>>s; len = s.length(); // 字符串的长度,就是对应数组(a,b数组)的长度 /* i: 表示arr数组的下标,从1开始到len(不从零开始存,方便记忆) j: 表示s字符数组的下标,从结尾len开始到1 s[j]-'0': s[j]得到的是一个字符数字,这个字符数字想要转成真正的数字需要减去0,详见ASCII码表 */ for(int i=0,j=len-1;j>=0;i++,j--){ arr[i] = s[j]-'0'; } } void addData(int *a,int *b,int &len){ // 1、得到a和b中最长的数组长度 len_ans = len_a; if (len_a<len_b){ len_ans = len_b; } // 做累加 t=0; // 进位,默认第一次累加为零 for(int i=0;i<len_ans;i++){ ans[i] = a[i]+b[i]+t; t=0; // 每次累加完之后归零,并不是每次都有进位 // 进位维护,如果累加之后结果大于等于10,进位变1,结果%10 if(ans[i]>=10){ t = 1; ans[i]=ans[i]%10; } } // 累加完了之后判断最后进位t是否等于1,是的话说明还有一位数,我们手动加到数组中 if(t==1){ len_ans++; ans[len_ans-1]=1; } } void reversePrint(){ // 最后一个位置是len_ans-1,所以从ans[len_ans-1]开始判断 while(ans[len_ans-1]==0&&len_ans-1>0){ len_ans--; } // 逆序输出 for(int i=len_ans-1;i>=0;i--){ cout<<ans[i]; } }
2.不使用函数形式
#include <iostream> #include <string> using namespace std; // 1. 创建变量(包括三个数组、数组的大小N、三个数组的长度) const int N = 520; int a[N],b[N],ans[N],len_a,len_b,len_ans,t; int main(){ // 2. 读入数据并倒置 string s; cin>>s; len_a = s.length(); for(int i=0,j=len_a-1;j>=0;i++,j--){ a[i] = s[j]-'0'; } cin>>s; len_b = s.length(); for(int i=0,j=len_b-1;j>=0;i++,j--){ b[i] = s[j]-'0'; } // 1、得到a和b中最长的数组长度 len_ans = len_a; if (len_a<len_b){ len_ans = len_b; } // 做累加 t=0; // 进位,默认第一次累加为零 for(int i=0;i<len_ans;i++){ ans[i] = a[i]+b[i]+t; t=0; // 每次累加完之后归零,并不是每次都有进位 // 进位维护,如果累加之后结果大于等于10,进位变1,结果%10 if(ans[i]>=10){ t = 1; ans[i]=ans[i]%10; } } // 累加完了之后判断最后进位t是否等于1,是的话说明还有一位数,我们手动加到数组中 if(t==1){ len_ans++; ans[len_ans-1]=1; } // 最后一个位置是len_ans-1,所以从len_ans-1开始判断 while(ans[len_ans-1]==0&&len_ans-1>0){ len_ans--; } // 逆序输出 for(int i=len_ans-1;i>=0;i--){ cout<<ans[i]; } return 0; }
优化
程序代码还可以在进行优化,例如数组倒置,或者是求取len_a和len_b中的最大值,都可以使用algorithm头文件进行处理,这里就自行查阅数据学习了。
初次学习,写的不足或者看不懂的地方请留言。
-
算法-基础算法- 高精度计算- 高精度加法(包含源程序).rar
2021-09-16 22:48:38算法-基础算法- 高精度计算- 高精度加法(包含源程序).rar -
高精度计算(附高精度加法程序)
2017-05-05 20:36:10有些数值计算要求精度高,希望计算的位数可达几十位甚至几百位,虽然计算机的计算精度也算较高了,但因受到硬件的限制,往往打不到实际问题所要求的精度,利用计算机处理高精度计算应注意以下问题: 数据的接收与...高精度计算
有些数值计算要求精度高,希望计算的位数可达几十位甚至几百位,虽然计算机的计算精度也算较高了,但因受到硬件的限制,往往达不到实际问题所要求的精度,利用计算机处理高精度计算应注意以下问题:
<1>数据的接收与存贮
①利用字符串读入数据
a[i]=s[s.length()-i]-'0';
②直接用循环加数组方法输入数据
注意:倒序存储
<2>确定位数
位数即为字符串长度
<3>进位,借位处理
①加法进位
c[i]=a[i]+b[i];
if(c[i]>=10){c[i]%=10;c[i+1]++;}
②减法借位
if(a[i]<b[i]){a[i+1]--;a[i]+=10;}
c[i]=a[i]-b[i];
③乘法进位
c[i+j-1]=a[i]*b[i]+x+c[i+j-1];
x=c[i+j-1]/10;
c[i+j-1]%=10;
<4>商和余数的求法:视被除数和除数的位数情况进行处理
下附高精度加法C++程序
#include<cstdio> #include<cstring> using namespace std; int main() { char a1[100],b1[100]; int a[100],b[100],c[100],lena,lenb,lenc,i,x; memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); memset(c,0,sizeof(c)); printf("加数1:"); gets(a1); printf("加数2:"); gets(b1); lena=strlen(a1); lenb=strlen(b1); for (i=0;i<=lena-1;i++) a[lena-i]=a1[i]-48; for (i=0;i<=lenb-1;i++) b[lenb-i]=b1[i]-48; lenc=1; x=0; while(lenc<=lena||lenc<=lenb) { c[lenc]=a[lenc]+b[lenc]+x; x=c[lenc]/10; c[lenc]%=10; lenc++; } c[lenc]=x; if (c[lenc]==0) lenc--; printf("和: "); for (i=lenc;i>=1;i--) { printf("%d",c[i]); } printf("\n"); return 0; }
-
高精度加法.zip
2021-12-04 12:37:39蓝桥杯VIP题和题解 -
汇编语言,双精度加法运算
2019-12-11 08:57:58要求计算X+Y=Z,将结果Z输出到屏幕上,其中X=001565A0H,Y=0021B79EH。实验利用累加器AX,先求低十六位和,并存入地址存储单元,后求高16位和,再存入高址存储单元。由于地位可能向高位有进位...二进制双精度加法运算...要求计算X+Y=Z,将结果Z输出到屏幕上,其中X=001565A0H,Y=0021B79EH。实验利用累加器AX,先求低十六位和,并存入地址存储单元,后求高16位和,再存入高址存储单元。由于地位可能向高位有进位,因而高位相加语句需用ADC指令,则地位相加有进位时,CF=1,高位字相加时,同时加上CF中的1。在80386以上微机中可以直接使用32位寄存器和32位加法指令完成。
;二进制双精度加法运算STACK1 SEGMENT STACK DW 256 DUP(?) STACK1 ENDS DATA SEGMENT MES1 DB 'The result is:$' XL DW 65A0H XH DW 0015H YL DW 0B79EH YH DW 0021H DATA ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA START: MOV AX,DATA MOV DS,AX MOV DX,OFFSET MES1 ;将MES1偏移地址给DX MOV AH,09H ;将MES1中的内容输出到屏幕 INT 21H MOV AX,XL ADD AX,YL MOV BX,AX MOV AX,XH ADC AX,YH PUSH BX ;入栈保存BX CALL SHWORD ;先去执行SHWORD POP BX ;返回继续执行BX出栈处理 MOV AX,BX ;此时AX中是低16位之和 CALL SHWORD ;再次调用SHWORD MOV AX,4C00H INT 21H SHWORD PROC NEAR MOV BL,AH ;保持高16位的高8位 CALL SHOW ;显示结果 MOV BL,AL ;保持高16位的低8位 CALL SHOW ;显示结果 RET ENDP SHOW PROC NEAR PUSH AX ;保持AX PUSH DX ;保存DX MOV AL,BL AND AL,0F0H ;AL与0F0H相与取高4位 SHR AL,4 CMP AL,0AH ;是否是A以上的数 JB C2 ADD AL,07H ;A以上的数加07H折显示的是字母 C2: ADD AL,30H MOV DL,AL ;show character MOV AH,02H INT 21H MOV AL,BL AND AL,0FH ;AL与0FH相与取低4位 CMP AL,0AH JB C3 ADD AL,07H C3: ADD AL,30H MOV DL,AL ;show character MOV AH,02H INT 21H POP DX POP AX RET ENDP CODE ENDS END START
-
二进制双精度加法运算
2020-10-15 23:45:17本实验要求计算 X+Y=Z,将结果 Z 输出到屏幕,其中 X=001565A0H,Y=0021B79EH。... 在 80386 以上微机中可以直接使用 32 位寄存器和 32 位加法指令完成本实验的功能。 DATA SEGMENT MES DB 'The resu -
高精度-高精度加法
2021-12-26 22:26:50高精度加法 -
高精度加法减法乘法除法
2010-08-24 22:15:09高精度 加法 减法 乘法 除法。你想要的全部囊括了! -
高精度加法(C语言实现)
2018-08-09 17:58:46那么,先来讲一下高精度加法吧! 源代码&amp;amp;amp;amp;amp;amp;amp;amp;注释 //小程序版 #include&amp;amp;amp;amp;amp;amp;amp;lt;stdio.h&amp;amp;amp;amp;amp;amp;amp... -
python实现高精度加法
2021-05-29 15:31:45有的时候由于两个相加的数字太大了,所以在相加的时候可能会出现溢出的情况,这个时候就可以使用高精度加法来解决这个问题。高精度加法主要使用数组或者列表来存储两个加数对应位置上的数字(两个相加的数字太大所以... -
高精度加法
2021-12-07 15:49:50高精度加法 就是对两个长度(位数)很大的数进行加法,无法用正常加法求解,可以采用下面的方法 高精度加法的原理采用小学学的列竖式的方法求解 当本位两个数之和大于等于10,要向下一位进1; 下一位对应两个... -
[汇编语言]子程序设计之多精度十进制加法
2020-09-11 21:58:03(1)将两个多精度十进制数相加。 (2)编写一个程序,他以二进制形式显示EAX中32位数据,并设计一个主程序验证。 (3)利用十六进制字节显示子程序DISPHB设计一个从低地址到高地址逐个字节显示某个主存区域内容的... -
数据结构与算法-高精度加法
2021-11-17 15:34:20高精度加法1.概念2.存储大小的问题3.进位问题4.补0问题5.处理进位溢出的问题6.总结二.代码三.解题思路四.图形解释 一.高精度加法 1.概念 高精度:处理位数较大的数学计算方法。 低精度:处理位数较低的数学计算方法... -
蓝桥杯java高精度加法
2021-03-09 18:53:47高精度加法的应用 Fibonacci数列 Fibonacci数列的代表问题是由意...C语言-进制转化及高精度加法._数学_高中教育_教育专区。C语言-进制转化及高精度加法. 感谢! C语言-进制转化及高精度加法. 感谢! ...c语言 高精度加... -
高精度加法(C++实现)
2020-10-16 23:55:06【算法分析】 1.C++不支持大数运算,故而引入高精度算法。 2.高精度算法将大数以字符串形式输入,然后拆分转换为一位一位的...【程序代码】 #include <bits/stdc++.h> using namespace std; int a[100],b[10 -
C++实现高精度加法、高精度减法、高精度乘法、高精度减法及思路注释
2021-10-06 15:19:24早在学习斐波那契数列兔子繁殖问题的时候,超过一定输入值的运算结果值会发生溢出,当时带我的于老师就有提了一句我的程序该如何处理大数据运算的问题,多年之后(?!你还好意思说),我终于又有了一个机会来学习... -
c++高精度---加法(csdn)————程序.pdf
2021-12-01 00:20:25c++高精度---加法(csdn)————程序 -
C++: 高精度加法与高精度减法
2016-03-23 17:21:59其实高精度加法、减法比乘法简单多了,所以可以通过高精度乘法这篇文章来入门高精度的算法。现在是用C++实现,显然有了string类,一切的操作都变的简单多了。题目如下:(Author: 欧文杰(TA)) This is an easy big ... -
P1601 A+B Problem(高精)(洛谷题解) 高精度加法
2021-04-06 16:07:28文章目录题目描述一、高精度加法二、题解1.字符数组置逆2.值得注意的是...3.运行与测试写在最后 题目描述 高精度加法,相当于a+b problem,不用考虑负数. 输入格式 分两行输入。a,b≤10500a,b \leq 10^{500}a,b≤... -
[LeetCode]67. 二进制求和(java实现)高精度加法
2022-03-04 10:40:47二进制求和(java实现)高精度加法1. 题目2. 读题(需要重点注意的东西)3. 解法4. 可能有帮助的前置习题5. 所用到的数据结构与算法思想6. 总结 1. 题目 2. 读题(需要重点注意的东西) 思路(高精度加法): 解题... -
C++ 高精度加法运算(a=a+b)
2019-01-16 16:13:53利用计算机进行数值计算,有时计算要求精度高,希望计算的数的位数达到上百或者上千,甚至更多。但是由于计算机硬件问题,往往达不到实际问题所要求的精度。 二、思路: 1.考虑如何接收输入的大整数 用... -
用C语言实现高精度加法
2011-05-12 11:25:04用户输入两个任意长度的数字,程序能够算出二者之和,利用c语言实现了高精度。 -
用C++实现高精度加法运算
2016-03-31 09:56:42先说说高精度运算的概念: 是指参与运算的数(加数,减数,因子……)范围大大超出了标准数据类型(整型,实型)能表示的范围的运算。例如,求两个200位的数的和。这时,就要用到高精度算法了。(摘自百度百科)。 -
(汇编语言)实验六 子程序设计之多精度十进制加法
2020-06-12 22:42:581)将两个多精度十进制数相加。 2)要求被加数和加数均以组合BCD码形式各自存放在以DATA1和DATA2为首的连续的5个内存单元中,结果送回被加数单元。 2.要求: 1)编写一个程序,他以二进制形式显示EAX中32位数据,并... -
高精度加法-小妙招 (C/C++语言代码)
2021-05-24 06:00:17声明:本文引自一篇优质题解:编译环境:WindowsChina HuaWei source Insight 4.0Linux Debain Ubuntu/Kali g++程序测试:解题思路:基本思路为使用一个数组将所需要求得大数字存起来,然后进行倒序相加,发现超过十之后...