专栏文章
高精度保姆级教学!
算法·理论参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mio7z8dj
- 此快照首次捕获于
- 2025/12/02 14:51 3 个月前
- 此快照最后确认于
- 2025/12/02 14:51 3 个月前
引入
解决
小董刚刚上完模拟课,于是有了一个大胆的想法:既然系统自带的加号不行,那我自己写总可以了吧!
这个方法便是高精度。
那么如何实现呢?很简单,模拟加法竖式。
考虑从个位将两个数逐位相加。此时我们发现有的位上的数之和成了两位数。那就遵循加法竖式的原则,向下一位进位即可。
CPP#include <bits/stdc++.h>
using namespace std;
int a[105], b[105], ans[105];
int main()
{
string str1, str2;
cin >> str1 >> str2;
for (int i = str1.length() - 1; i >= 0; i--)
{
a[str1.length() - i] = str1[i] - '0';
}
for (int i = str2.length() - 1; i >= 0; i--)
{
b[str2.length() - i] = str2[i] - '0';
}
for (int i = 1; i <= max(str1.length(), str2.length()) + 1; i++)
{
ans[i] += a[i] + b[i];
if (ans[i] >= 10)
{
ans[i] -= 10;
ans[i + 1]++;
}
}
bool flg = false;
for (int i = max(str1.length(), str2.length()) + 1; i >= 1; i--)
{
if (ans[i] != 0)
flg = true;
if (flg)
cout << ans[i];
}
}
继续继续!小董已经求知若渴了!
同理同理,我们也可以写出减法!
同样,代码并不长,也很好理解。
CPP#include <bits/stdc++.h>
using namespace std;
int a[105], b[105], ans[105];
int main()
{
string str1, str2;
cin >> str1 >> str2;
for (int i = str1.length() - 1; i >= 0; i--)
{
a[str1.length() - i] = str1[i] - '0';
}
for (int i = str2.length() - 1; i >= 0; i--)
{
b[str2.length() - i] = str2[i] - '0';
}
for (int i = 1; i <= max(str1.length(), str2.length()) + 1; i++)
{
ans[i] += a[i] - b[i];
if (ans[i] < 0)
{
ans[i] += 10;
ans[i + 1]--;
}
}
bool flg = false;
for (int i = max(str1.length(), str2.length()) + 1; i >= 1; i--)
{
if (ans[i] != 0)
flg = true;
if (flg)
cout << ans[i];
}
}
推广
小董寻思着,要是乘法的数据范围也很大呢?于是,聪明的他又想到了高精度!
与刚才同样的原理,运用乘法竖式去模拟。这个就比较复杂了,建议各位同学自己去画一下多体会一下。

以上就是全部要点了,更多细节请同学们看代码体会 (码风较丑,见谅)。
CPP#include <bits/stdc++.h>
using namespace std;
int a[105], b[105];
int ans[505], ccc[505];
char c[105], d[105];
signed main()
{
cin >> c + 1 >> d + 1;
int lenc = strlen(c + 1);
int lend = strlen(d + 1);
for (int i = 1; i <= lenc; i++)
{
a[i] = c[lenc - i + 1] - '0';
}
for (int i = 1; i <= lend; i++)
{
b[i] = d[lend - i + 1] - '0';
}
for (int i = 1; i <= lend; i++)
{
int pos = i - 1;
memset(ccc, 0, sizeof ccc);
for (int j = 1; j <= lenc; j++)
{
int tmp = a[j] * b[i] + ccc[j];
ccc[j] = tmp % 10;
ccc[j + 1] = tmp / 10;
}
for (int k = 1 + pos; k <= max(lenc, lend) + 1 + pos; k++)
{
ans[k] += ccc[k - pos];
}
}
for (int i = 1; i <= 503; i++)
{
ans[i + 1] += ans[i] / 10;
ans[i] %= 10;
}
bool flg = false;
for (int i = 504; i >= 1; i--)
{
if (ans[i] != 0 && !flg)
flg = true;
if (flg)
cout << ans[i];
}
}
进阶
聪明的小董再次想到,有了乘法怎么能把除法落了呢?!
除法个人认为要比乘法简单些,直接看代码吧,有很多都是同学们看到前两部分后就能推出来的,希望同学们多多思考一下。
以下这份代码是求出 与 的。
CPP#include <bits/stdc++.h>
using namespace std;
int lt;
int a[105], b;
int k[105];
int main()
{
char c[105];
cin >> c + 1;
int lenc = strlen(c + 1);
for (int i = 1; i <= lenc; i++)
{
a[i] = c[i] - '0';
}
cin >> b;
int lena = lenc;
int tmp = 0;
for (int i = 1; i <= lena; i++)
{
tmp = tmp * 10 + a[i];
k[i] = tmp / b;
lt = tmp % b;
tmp = lt;
}
bool flg = false;
for (int i = 1; i <= lena; i++)
{
if (k[i] != 0 || flg)
{
cout << k[i];
flg = true;
}
}
if (!flg)
cout << 0;
cout << endl << lt << endl;
return 0;
}
尾声
小董终于掌握了全部高精度的知识!
作者:zzx
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...