高精度|大数加减乘

2024-06-09 19:52
文章标签 大数 高精度 加减

本文主要是介绍高精度|大数加减乘,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、大数加法

1.反转法 (不开动态数组存)

#include<bits/stdc++.h>
using namespace std;
string add(string s1,string s2){if(s1.length() < s2.length() ) swap(s1,s2);reverse(s1.begin(),s1.end());reverse(s2.begin(),s2.end());int carry = 0;for(int i = 0 ; i < s2.length() ; i++){int sum = (s1[i] - '0') + (s2[i] - '0') + carry;s1[i] = sum%10 + '0';carry = sum / 10;}for(int i = s2.length() ; i < s1.length() ; i++){int sum = s1[i]-'0' + carry;s1[i] = sum % 10 + '0';carry = sum /10;}if(carry) {s1.push_back(carry + '0');}reverse(s1.begin() , s1.end());return s1.empty() ? 0 : s1;
}
int main(){string num1,num2;cin>>num1>>num2;string num = add(num1,num2);cout<<num<<endl;
}

2.开数组存

#include<bits/stdc++.h>
using namespace std;
string add(string s1,string s2){int len1 = s1.length() - 1;int len2 = s2.length() - 1;int carry = 0;string result;//动态数组保存答案 vector<char> result;while(len1 >=0 || len2 >=0 ){int n1 = len1 >=0 ? (s1[len1--] - '0') : 0;//大端方式(从个位计算) int n2 = len2 >=0 ? (s2[len2--] - '0') : 0; int sum = n1 + n2 + carry;carry = sum /10;result.push_back(sum%10+'0');}//始终对进位要处理 if(carry > 0 ){result.push_back(carry + '0');}reverse(result.begin(),result.end());//调用vector数组即能够反转,也能转化为字符串 //string r1(result.rbegin() , result.rend());return r1;	
}
int main(){string num1,num2;cin>>num1>>num2;string num = add(num1,num2);cout<<num<<endl;
}

二、大数减法

加负号 + 交换两数

1.数字1.length() < 数字2.length();
2.两数字长度相同,但数字1 < 数字2

#include<bits/stdc++.h>
using namespace std;string subtract(string num1,string num2){if(num1.size() < num2.size() || (num1.size() == num2.size() && num1 < num2)){return "-" + subtract(num2,num1);//交换两个数并返回负数形式。 }string result = " ";int len1 = num1.size()-1;int len2 = num2.size()-1;int borrow = 0;//计算 while(len1 >= 0 || len2 >= 0){int n1 =len1 >= 0 ? num1[len1--]-'0':0;int n2 = len2 >= 0 ? num2[len2--]-'0':0;int sub = n1 - n2 - borrow;//个位减法后观察是否借位 if(sub<0){sub+= 10;borrow = 1;}else borrow = 0;//将结果保存 result.push_back(sub+'0');} //去除前导零 while(result.size() >1 && result.back() =='0') result.pop_back();//反转 reverse(result.begin(),result.end());return result;
}
int main(){string num1,num2;cin>>num1>>num2;string num = subtract(num1,num2);cout<<num<<endl;
}

总结:

大数加减法主要使用借位和进位的方式,并且都可以采用string进行存储,随后反转结果,只不过减法,1. 交换两数 + 要加负号,2.要对多余的前导零(直接丢掉)pop_back()

三、大数乘法

两种思路在for循环不同,第一个好理解也好模拟,但是注意加法的位置**(错位相加)**

#include<bits/stdc++.h>
#define N 1001
using namespace std;
string multiply(string num1,string num2){if(num1 == "0" || num2 == "0") return "0";reverse(num1.begin(), num1.end());reverse(num2.begin(),num2.end());int len1 = num1.size();int len2 = num2.size();vector<int> result(len1 + len2,0);for (int i = 0; i < len1; ++i) {for (int j = 0; j < len2; ++j) {//重点:之前的本位 + 该位结果 = 现在本位result[i + j] += (num1[i] - '0') * (num2[j] - '0'); // 直接累加到结果的相应位置//求进位result[i + j + 1] += result[i + j] / 10; // 处理进位//更新本位result[i + j] %= 10; // 更新当前位的值}}string strResult;for(int i = result.size() - 1 ; i >= 0 ;--i){//去除前导零 if(strResult.empty() && result[i] == 0) continue;strResult.push_back(result[i] +'0');}return strResult.empty() ? "0": strResult;
}
int main(){string num1,num2;cin>>num1>>num2;string result = multiply(num1,num2);cout<<result<<endl;
}
#include<bits/stdc++.h>
using namespace std;string subtract(string num1,string num2){int len1 = num1.size();int len2 = num2.size();vector<int> result(len1+len2,0);//这个不好理解啊for(int i = len1-1;i>=0;i--){for(int j =len2-1 ; j>=0 ;j--){int mul = (num1[i] - '0') * (num2[j] -'0');int sum = result[i+j+1] + mul;result[i+j+1] = sum%10;//保存个位数 result[i+j] += sum /10;//进位 }}string strResult;//忽略前导零存数字 for(int digit : result){if(!(strResult.empty() && digit == 0)){strResult.push_back(digit + '0');}} return strResult.empty() ? "0":strResult;
}int main(){string num1,num2;cin>>num1>>num2;string num = subtract(num1,num2);cout<<num<<endl;
}

总结

大数乘法注意1. 使用动态数组存
2.去除前导零(遍历去除)

当然洛谷里面的这个题解看起来更简单易懂

四、大数除法

结合加法减法乘法进行操作,比较复杂

这篇关于高精度|大数加减乘的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1046139

相关文章

uva 10069 DP + 大数加法

代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vector>#include <queue>#include <map>#include <cl

加减密签名

签名,验签的理解(转)图片理解数字签名和验签过程

Java验证辛钦大数定理

本实验通过程序模拟采集大量的样本数据来验证辛钦大数定理。   实验环境: 本实验采用Java语言编程,开发环境为Eclipse,图像生成使用JFreeChart类。   一,验证辛钦大数定理 由辛钦大数定理描述为: 辛钦大数定理(弱大数定理)  设随机变量序列 X1, X2, … 相互独立,服从同一分布,具有数学期望E(Xi) = μ, i = 1, 2, …, 则对于任意正数ε ,

高精度计算(代码加解析,洛谷p1601,p1303)除法待更新

目录 高精度加法 高精度减法 高精度乘法 高精度加法 我们知道在c++语言中任何数据类型都有一定的表示范围。当两个被加数很大时,正常加法不能得到精确解。在小学,我们做加法都采用竖式方法。那么我们也只需要按照加法进位的方式就能得到最终解。 8 5 6+ 2 5 5-------1 1 1 1 加法进位: c[i] = a[i] + b[i];if(c[i] >=

高精度打表-Factoring Large Numbers

求斐波那契数,不打表的话会超时,打表的话普通的高精度开不出来那么大的数组,不如一个int存8位,特殊处理一下,具体看代码 #include<stdio.h>#include<string.h>#define MAX_SIZE 5005#define LEN 150#define to 100000000/*一个int存8位*/int num[MAX_SIZE][LEN];void

高精度计算----减法运算(浮点型)

基于上一贴,修改减法运算适合于高精度浮点型计算。 因为减法比加法难度大一点,考虑的地方也要多一些,可能代码有欠缺,欢迎指出。 运算说明: 1、相减函数依旧没改变,包括上一贴的判断被减数与减数的大小函数也没变。 2、增加两个函数,取小数位数函数和结果处理(回归小数点)函数 3、与加法浮点高精度运算相比,这里改变较多的是结果处理函数,加法加完后,位数不减反增,而且最多增一位。减法会消失掉好多

高精度计算----减法运算

处理大数减法运算: 1、首先要判断被减数与减数哪个更大,再相应的带入减法函数去处理。具体的比较可以使用字符串的相关知识去比较。 2、相减要先对齐数组,依照减数的长度,执行相应的减法运算次数。 3、不需要借位相减的话,直接减去;需要的话,向前借一位,若前一位是0,则再前借(此时前一位的0变为10)。 测试程序效果如下:   以下代码包括相减函数,比较被减数减数函数,若有错误,请指出:

高精度加法,乘法,阶乘

#include <iostream>#include <map>#include <string>#include <algorithm>using namespace std;const int Max = 50000;string str1,str2;/***********乘法***********/void chenfa(){cin >> str1>>str2;int a

找第K大数(ACdream 1099)

瑶瑶的第K大 Time Limit: 4000/2000MS (Java/Others)  Memory Limit: 256000/128000KB (Java/Others) Submit  Statistic  Next Problem Problem Description 一天,萌萌的妹子--瑶瑶(tsyao)很无聊,就来找你玩。可是你们都不知道玩什么。。。