本文主要是介绍秒懂百科,C++如此简单丨第十八天:高精度,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
目录
前言
模拟运算
高精度加法模版
优化
高精度减法模版
高精度乘法模版
结尾
必看信息
▶本篇文章由爱编程的小芒果原创,首发于CSDN,未经许可,严禁转载。
▶本篇文章被收录于秒懂百科,C++如此简单专栏,欢迎订阅。
☆专栏亮点☆
1.每篇文章质量高,质量分保证在80分以上。
2.文章的内容清晰有条理,图文并茂,附有源代码。
3.每个知识点讲解详细,会有很多补充扩展。
4.若哪个知识点没有懂,可以私信我,我会尽可能地帮助你。
前言
在编程中,我们常常会遇到一些极大的数字。这些数字用long long和double是根本存不下的,所以这节课我们将介绍高精度。
模拟运算
高精度说白了就是模拟运算,首先我们先想一想在生活中我们是怎样计算整数加法的。
1 | 2 | 3 | 4 | 5 | |
+ | 7 | 8 | 7 | 6 | 5 |
= | 9 | 1 | 1 | 1 | 0 |
在计算的过程中,我们会遇到一个特殊情况——进位。
如在计算个位的时候,5+5=10,写0进1,十位4+6+1=11,写1进1。
遇到这种情况该怎么办呢?因为我们知道一个原则“满十进一” ,那么两个数相加在一起一共有多少个整十,是不是就要进几?如8+9=17,有一个整十,所以要进一,以此类推。
而判断一个数由多少个整十最好的方法就是——除法,我们用一个数除以10,得到的就是一个数由几个十组成,注意:这里因为是整数,所以除法是会保留整数,而一个数对10取余不就是余下来的几个一吗?思路知道了,程序也就简单了。
高精度加法模版
#include<bits/stdc++.h>
using namespace std;
const int N=510; //定义足够大的数组来存储大整数的每一位
int a[N],b[N],c[N];
int main()
{ string str1,str2; cin>>str1>>str2;// 将字符串逆序存储到数组中,方便从低位到高位进行加法运算 for (int i = 0; i < str1.size(); i++) a[str1.size() - 1 - i] = str1[i] - '0'; for (int i = 0; i < str2.size(); i++) b[str2.size() - 1 - i] = str2[i] - '0'; //确定最大长度 int len = max(str1.size(), str2.size()); //进行高精度加法运算 for (int i = 0; i < len; i++) { c[i] += a[i] + b[i]; c[i + 1] += c[i] / 10; //进位 c[i] %= 10; //取当前位的值 } //处理最高位的进位 if (c[len] > 0) { len++; //如果最高位有进位,则长度加1 } //逆序输出结果 for (int i = len - 1; i >= 0; i--) { cout << c[i]; } return 0;
}
优化
因为我们知道两个数相加最多是18(9+9),那么进位最多是1,所以进位也可以写成这样。
for (int i = 0; i < len; i++) { c[i] += a[i] + b[i]; if(c[i]>=10) {c[i]-=10;c[i+1]+=1;} }
高精度减法模版
高精度减法只需要把“进位”修改成“退位”即可。但需要注意以下几点:
1.判断正负数,如果A<B需要先输出一个负号,并交换A和B。
2.需要借位,千万不要写成进位了。
3.前导零可能不止一个,不要用if,用while循环。
4.如果答案为0,记得额外输出一个0。
#include<bits/stdc++.h>
using namespace std;
const int N=510;
int a[N],b[N],c[N];
int main()
{ string str1, str2; cin >> str1 >> str2; // 确保str1 >= str2,这里不处理str1 < str2的情况 if (str1.size() < str2.size() || (str1.size() == str2.size() && str1 < str2)) { cout << "-" << endl; // 输出负号,实际应用中需要更完整的处理 swap(str1, str2); // 交换两个字符串,使得str1始终为较大的数 } // 将字符串逆序存储到数组中 for (int i = 0; i < str1.size(); i++) a[str1.size() - 1 - i] = str1[i] - '0'; for (int i = 0; i < str2.size(); i++) b[str2.size() - 1 - i] = str2[i] - '0'; int len = max(str1.size(), str2.size()); for (int i = 0; i < len; i++) { if (a[i] < b[i]) { // 需要借位 a[i + 1]--; // 从高位借1 a[i] += 10; // 当前位加10 } c[i] = a[i] - b[i]; // 进行减法运算 } // 跳过前导零 int start = len - 1; while (start >= 0 && c[start] == 0) { start--; } // 输出结果 if (start >= 0) { for (int i = start; i >= 0; i--) { cout << c[i]; } } else { cout << "0"; // 如果结果为0,则输出0 } return 0;
}
高精度乘法模版
注意以下几点:
1.乘法的每一数位都要和另一个数的每一数位相乘。2.注意数组c不要开太小了。
#include<bits/stdc++.h>
using namespace std;
const int N=510; // 数组大小,用于存储大整数的每一位
int a[N],b[N],c[N*2]; // c数组的大小为2*N,因为两个N位数相乘的结果可能接近2N位
int main()
{ string str1, str2; cin >> str1 >> str2; // 将字符串逆序存储到数组中,方便从低位到高位进行计算 for (int i = 0; i < str1.size(); i++) a[str1.size() - 1 - i] = str1[i] - '0'; for (int i = 0; i < str2.size(); i++) b[str2.size() - 1 - i] = str2[i] - '0'; // 高精度乘法 memset(c, 0, sizeof(c)); // 初始化c数组为0 for (int i = 0; i < str1.size(); i++) { for (int j = 0; j < str2.size(); j++) { c[i + j] += a[i] * b[j]; // 计算乘积并加到对应位置 c[i + j + 1] += c[i + j] / 10; // 处理进位 c[i + j] %= 10; // 取当前位的值 } } // 跳过前导零 int start = str1.size() + str2.size() - 1; while (start >= 0 && c[start] == 0) { start--; } // 输出结果 if (start >= 0) { for (int i = start; i >= 0; i--) { cout << c[i]; } } else { cout << "0"; // 如果结果为0,则输出0 } return 0;
}
结尾
本节课我们一起学习了高精度,还有高精度除法没有写,留给你自己写一写吧。
如果你觉得还不错的话,记得点赞收藏评论哦,下课!
这篇关于秒懂百科,C++如此简单丨第十八天:高精度的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!