【算法】高精度
一.问题引入
第十五届蓝桥杯省赛B组第四题:

❌错误解法(未使用高精度算法使得测试数据超出范围)
cpp
#include <iostream>
#include<math.h>
using namespace std;
int main()
{
int n;
long double d;
cin>>n>>d;
d*=pow(2,n);
long long ans=d;
if((int)(d*10)%10>=5)
{
ans+=1;
cout<<ans;
}
else
{
cout<<ans;
}
return 0;
}
二.高精度算法概念
1.为什么需要高精度?
C 语言基本数据类型有上限:
int :最大约 20 亿(10 位)
long long :最大约 9e18(18 位)
如果要算 100 位 + 100 位、50 位 × 50 位,普通变量直接溢出,只能用数组存每一位数字,模拟人笔算的过程。
2.高精度核心规则
倒序存储(个位存在数组下标 0)
比如数字 1234,存成:a[0]=4, a[1]=3, a[2]=2, a[3]=1
好处:进位、对位计算最方便。
用int 数组存每一位(不要用 char,计算更方便)。
模拟竖式运算过程。
三.高精度算法模板
1.高精度加法
cpp
string add(string a, string b)
{
string res;
int i = a.size() - 1;
int j = b.size() - 1;
int carry = 0;
while (i >= 0 || j >= 0 || carry > 0)
{
int sum = carry;
if (i >= 0)
{
sum += a[i] - '0';
i--;
}
if (j >= 0)
{
sum += b[j] - '0';
j--;
}
carry = sum / 10;
res.push_back(sum % 10 + '0');
}
reverse(res.begin(), res.end());
return res;
}
2.高精度减法
cpp
bool cmp(string a, string b)
{
if (a.size() != b.size())
{
return a.size() > b.size();
}
return a >= b;
}
//高精度减法
string sub(string a, string b)
{
bool negative = false;
if (!cmp(a, b))
{
negative = true;
swap(a, b);
}
string res;
int i = a.size() - 1;
int j = b.size() - 1;
int borrow = 0;
while (i >= 0)
{
int x = a[i] - '0';
int y = 0;
if (j >= 0)
{
y = b[j] - '0';
j--;
}
x = x - borrow;
borrow = 0;
if (x < y)
{
x = x + 10;
borrow = 1;
}
res.push_back(x - y + '0');
i--;
}
while (res.size() > 1 && res.back() == '0')
{
res.pop_back();
}
reverse(res.begin(), res.end());
if (negative)
{
res = "-" + res;
}
return res;
}
3.高精度乘法
cpp
string mul(string a, string b)
{
int n = a.size();
int m = b.size();
vector<int> res(n + m, 0);
for (int i = n - 1; i >= 0; i--)
{
for (int j = m - 1; j >= 0; j--)
{
int x = a[i] - '0';
int y = b[j] - '0';
int pos = i + j + 1;
res[pos] = res[pos] + x * y;
res[pos - 1] = res[pos - 1] + res[pos] / 10;
res[pos] = res[pos] % 10;
}
}
string ans;
for (int k = 0; k < res.size(); k++)
{
int num = res[k];
if (!(ans.empty() && num == 0))
{
ans.push_back(num + '0');
}
}
if (ans.empty())
{
return "0";
}
return ans;
}
4.高精度除法
cpp
string div(string a, int b, int &rem)
{
string res;
rem = 0;
for (int i = 0; i < a.size(); i++)
{
int now = rem * 10 + (a[i] - '0');
int q = now / b;
rem = now % b;
res.push_back(q + '0');
}
while (res.size() > 1 && res[0] == '0')
{
res.erase(res.begin());
}
return res;
}