前言
在洛谷水题的时候发现本蒟蒻是连高精度都不会的蒟蒻中的蒟蒻,所以想要浅浅学习一下
什么是高精度算法
高精度算法(High Accuracy Algorithm)是处理大数字的数学计算方法。在一般的科学计算中,会经常算到小数点后几百位或者更多,当然也可能是几千亿几百亿的大数字。一般这类数字我们统称为高精度数,高精度算法是用计算机对于超大数据的一种模拟加,减,乘,除,乘方,阶乘,开方等运算。对于非常庞大的数字无法在计算机中正常存储,于是,将这个数字拆开,拆成一位一位的,或者是四位四位的存储到一个数组中, 用一个数组去表示一个数字,这样这个数字就被称为是高精度数。高精度算法就是能处理高精度数各种运算的算法,但又因其特殊性,故从普通数的算法中分离,自成一家。「摘自百度百科」
高精度加法
利用字符串存储数字,再利用小学数学的基础,模拟两个数字的相加和进位,不足的位数用0补齐,要注意的是:最后的结果可能是较大数的位数 + 1
来一个洛谷的题目小小练习一下,点击传送门:P1601 A+B Problem(高精)
蒟蒻的代码如下
#include <iostream>
#define int long long
std::string add(std::string a,std::string b){
std::string ans;
int lena = a.length();
int lenb = b.length();
if(lena > lenb){//在数字前面补0
for(int i = lenb;i < lena;i ++){
b = '0' + b;
}
}else {
for(int i = lena;i < lenb;i ++){
a = '0' + a;
}
}
int t;
int left = 0;//进位
for(int i = a.length() - 1;i >= 0;i --){
t = a[i] + b[i] - 2 * '0' + left;
ans = (char)(t % 10 + '0') + ans;
left = t / 10;
}
if(left != 0){//最后需要进位
ans = (char)('0' + left) + ans;
}
return ans;
}
signed main() {
std::string a,b;
std::cin>>a>>b;
std::cout<<add(a,b)<<'\n';
return 0;
}
高精度减法
减法的运算相较于加法还是复杂一点点,但也只是一点点。减法主要有两种情况,大减小或者小减大。所以,需要判断结果的符号,但是计算都是一样的,用绝对值大的数减去绝对值小的数。考虑清楚之后,就又是利用小学数学的基础,模拟两个数相减和借位。
老规则来个传送门:P2142 高精度减法
蒟蒻的代码如下相当丑陋且水平低下
#include <iostream>
#define int long long
std::string div(std::string a,std::string b){
std::string ans;
std::string real;
if(a == b){//如果a,b相等,结果为0
return "0";
}
bool flag = true;//判断是正数还是负数
if((a < b && a.length() == b.length()) || a.length() < b.length()) {
flag = false;
std::string t = a;//保证a是绝对值大的数
a = b;
b = t;
}
int lena = a.length();
int lenb = b.length();
if(lena > lenb){//在数字前面补0
for(int i = lenb;i < lena;i ++){
b = '0' + b;
}
}else {
for (int i = lena; i < lenb; i++) {
a = '0' + a;
}
}
int t;
int need = 0;//借位
for(int i = a.length() - 1;i >= 0;i --){
t = a[i] - b[i] - need;
need = 0;
while (t < 0){
t += 10;
need ++;
}
ans = (char) (t + '0') + ans;
}
if(!flag){
ans = '-' + ans;
}
bool zero = true;//去除前导0
for(int i = 0;i < ans.length();i ++){
if(ans[i] != '0'){
zero = false;
}
if(!zero){
real += ans[i];
}
}
return real;
}
signed main() {
std::string a,b;
std::cin>>a>>b;
std::cout<<div(a,b)<<'\n';
return 0;
}
阿巴阿巴
Q:为什么没有高精度乘法和除法?
A:下次再来填坑再不预习要挂科啦