高精度算法也称为大数运算,当运算结果很大的时候,就需要用到高精度算法,既数组储存整数
加法
加法运算时,从低位往高位每位相加,进位直接加到下一位上,模10后的余数就是c[i]
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5;
int a[N], b[N], c[N];
int la, lb, lc;
void add()
{
for (int i = 0; i < lc; ++i)
{
c[i] += a[i] + b[i]; // 累加
c[i + 1] += c[i] / 10; // 进位
c[i] %= 10; // 存余
}
if (!c[lc])
lc--; // 最后一位未进位时, lc减一
}
// 高精度加法
int main()
{
string s1, s2;
cin >> s1 >> s2;
la = s1.size(), lb = s2.size(), lc = max(la, lb);
for (int i = 0; i < la; ++i) // 倒序存储, 进位时下一位++即可
a[i] = s1[la - 1 - i] - '0';
for (int i = 0; i < lb; ++i)
b[i] = s2[lb - 1 - i] - '0';
add();
for (int i = lc; i >= 0; --i)
cout << c[i];
cout << endl;
return 0;
}
减法
题目:高精度减法 - 洛谷
先要对两数大小进行比较判断,当a<b时交换a,b,输出负号,再进行大数减小数
减法运算时,从低位往高位计算,当a[i] < b[i]时,a[i + 1]减1,c[i]加10,c[i]再加上a[i] - b[i]
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5;
int a[N], b[N], c[N];
int la, lb, lc;
bool cmp()
{
if (la != lb)
return la > lb;
for (int i = la - 1; i >= 0; --i)
if (a[i] != b[i])
return a[i] > b[i];
return true;
}
void sub()
{
for (int i = 0; i < la; ++i)
{
if (a[i] < b[i])
a[i + 1]--, c[i] += 10;
c[i] += a[i] - b[i];
}
while (lc && !c[lc]) // 处理多于零
lc--;
}
// 高精度减法
int main()
{
string s1, s2;
cin >> s1 >> s2;
la = s1.size(), lb = s2.size();
lc = max(la, lb); // 减时, 也取最大长度
for (int i = 0; i < la; ++i) // 存储
a[i] = s1[la - 1 - i] - '0';
for (int i = 0; i < lb; ++i)
b[i] = s2[lb - 1 - i] - '0';
if (!cmp())
swap(a, b), swap(la, lb), cout << '-'; // 使a大于b
sub();
for (int i = lc; i >= 0; --i)
cout << c[i];
cout << endl;
return 0;
}
乘法
乘法运算和加法类似,找规律发现
n == i + j
c[n] =(Sum(a[i] * b[j]) + 进位)模10
c[n]的进位 = c[n - 1]模10之前先除10;
#include <bits/stdc++.h>
using namespace std;
const int N = 4e6 + 10;
int a[N], b[N], c[N];
int la, lb, lc;
void mul()
{
for (int i = 0; i < la; ++i)
{
for (int j = 0; j < lb; ++j)
{
c[i + j] += a[i] * b[j]; // 累加
c[i + j + 1] += c[i + j] / 10; // 进位
c[i + j] %= 10; // 存余
}
}
while (lc && !c[lc]) // 处理多于零
lc--;
}
// 高精度乘法
int main()
{
string s1, s2;
cin >> s1 >> s2;
la = s1.size(), lb = s2.size(), lc = la + lb;
for (int i = 0; i < la; ++i)
a[i] = s1[la - 1 - i] - '0';
for (int i = 0; i < lb; ++i)
b[i] = s2[lb - 1 - i] - '0';
mul();
for (int i = lc; i >= 0; --i)
cout << c[i];
cout << endl;
return 0;
}
除法
高精除低精
除法运算时,从高位进行运算,通过定义变量r来计算当前的要被除数的大小
#include <bits/stdc++.h>
using namespace std;
const int N = 5e3 + 10;
int a[N], c[N];
int b, la, lc;
void div()
{
long long r = 0;
for (int i = la - 1; i >= 0; --i)
{
r = r * 10 + a[i]; // 被除数
c[i] = r / b; // 商
r %= b; // 余数
}
while (lc && !c[lc]) // 处理多于零
lc--;
}
// 高精度除法
int main()
{
string s;
cin >> s >> b;
lc = la = s.size();
for (int i = 0; i < la; ++i)
a[i] = s[la - 1 - i] - '0';
div();
for (int i = lc; i >= 0; --i)
cout << c[i];
cout << endl;
return 0;
}
练习题