——————出自南昌理工学院ACM集训队
我们用的最基础的运算方法有四种,加 减 乘 除。在进行进行加减乘除的运算中较小的数据时,我们的编译器是能够充分且快速的进行运算的,但是如果要运算的数据是很大很大,超过了int定义的数据范围的时候怎么办呢?这时候我们就要采用另一种的方法————高精度,来进行运算。
在这里我就介绍三种,加减乘(除法…emm,这里就不讲了)。
思路
高精度并没有看上去那么难,主要的思路就是把我们在草稿纸上的过程用代码来实现。
加法和减法就是把数字一个一个拆开了进行运算,主要正确处理好进位和借位的问题,乘法就比加法和减法复杂一些,但也差不了很多。因为进行大数据的运算,用int,longlong之类可能存不下,所以我们用数组来保存所要进行运算的数据并且用char来定义,把它们当成字符串来进行操作,并且我们是要把数字倒着存,这样方便一个一个位置进行操作
emm,输入输出都是一样的,所以我都写一起了。
我直接在代码里解释把。
#include <iostream>
#include <cstring>
#define maxn 10000
using namespace std;
int main()
{
//这些初始化和倒着存数据,加减乘都是一样的
char a[maxn], b[maxn];//两个数组用来存两个加的数据
int len1, len2;//保存两个数据的长度
int aa[maxn], bb[maxn];//倒着保存的数组
int c[maxn]
memset(aa, 0, sizeof(aa));//全部赋值为0
memset(bb, 0, sizeof(bb));
cin >> a;
cin >> b;
len1 = strlen(a);
len2 = strlen(b);
for (int i = 1; i <= len1; ++i) {//倒着保存两个输入的数
aa[i] = a[len1 - i] - '0';//-‘0’是因为我们定义的是char
}
for (int i = 1; i <= len2; ++i) {
bb[i] = b[len2 - i] - '0';
}
//加法关键步骤
if (len1 < len2) len1 = len2;
for (int i = 1; i <= len1; ++i) {//从最后一位往前加
aa[i] += bb[i];//两个数的一位相加
aa[i + 1] += aa[i] / 10;//有进位就加到后面a[i+1]上
aa[i] %= 10;//求余
}
if (aa[len1 + 1] > 0) len1++;//判断一下最前面一位是不是0,不是等下要输出要多加一位
//
//减法关键步骤
if ((len1 < len2) || ((len1 == len2) && strcmp(a, b) < 0)) {//第一个数比第二个小就要输出负号
cout << "-";
swap(aa, bb);//交换两个数和长度
swap(len1, len2);
}
for (int i = 1; i <= len1; i++) {//最后一位开始
if (aa[i] < bb[i]) {//小了就要借位
aa[i + 1]--;//借了位的要减一
aa[i] += 10;//借了之后就加十
}
aa[i] -= bb[i];//相减
}
while ((aa[len1] == 0) & (len1 > 1)) len1--;//判断最前面的是不是零,是的话输出的长度减一
//
//减法加法一样的输出
for (int i = len1; i >= 1; --i) {//反向输出
cout << aa[i];
}
//
//乘法关键步骤
int c[maxn],len3;//定义一个数组来存相乘的结果
memset(c,0,sizeof(c));
for (int i = 1; i <= len1; ++i) {
for (int j = 1; j <= len2; ++j) {
c[i + j - 1] += aa[i] * bb[j];//相乘存入数组
c[i + j] += c[i + j - 1] / 10;//进位加入前一位
c[i + j - 1] %= 10;//求余
}
}
len3 = len1 + len2;//不能确切的知道有多少位,所以只能从最大的长度开始往下减
while (c[len3] == 0 && len3 > 1) len3--;//为零就减一
for (int i = len3; i >= 1; --i) {
cout << c[i];
}
return 0;
}