高精度计算
主要进行的是大整数的四大计算;
使用数组存储;
正确处理借位、进位。
高精度加法
要点: 逐位从地位到高位相加,处理进位
-
题目描述 (Description)
输入两个大整数a,b,输出他们的和。(1<=a,b<=10^100) -
输入格式(Format Input)
输入两个大整数a和b。(1<=a,b<=10^100)
输出格式(Format Output)
输出a加b的和。 -
样例(Sample)
输入样例1 (Sample Input 1)
43434343445435343 32435647668754353
输出样例1 (Sample Output 1)
75869991114189696
#include <bits/stdc++.h>
using namespace std;
char aa[1001], bb[1001]; // 初始数据
int c[1002], a[1001], b[1001], la, lb, lc; // 数组c有可能产生进位
/*
aa, bb -- (char)用来收集输入的数据(0-n,高-低)
a, b -- (int)用来转换aa,bb数组(0-n,低-高),可以保证位数对齐
c -- 收集答案(a + b)
*/
int main()
{
// 1. 初始化 -- 对设置的数组先初始化元素
memset(a, 0, sizeof(a));
memset(b, 0, sizeof(b));
memset(c, 0, sizeof(c));
scanf("%s %s", aa + 1, bb + 1); // customize:从下标为1开始存储数据
la = strlen(aa + 1);
lb = strlen(bb + 1);
// 2. 位数对其(高位在后,低位在前) -- a, b
for(int i = 1; i <= la; i++)
a[i] = aa[la - i + 1] - '0'; // 转换成int类型
for(int i = 1; i <= lb; i++)
b[i] = bb[lb - i + 1] - '0';
// 3. 加法计算,结果保存到数组c中
// 计算数组c的长度 -- max(la, lb)
if(la > lb) lc = la;
else lc = lb;
// lc = max(la, lb);
// 计算每一位的结果
for(int i = 1; i <= lc; i++)
{
c[i] = a[i] + b[i] + c[i];
c[i + 1] += c[i] / 10;
c[i] %= 10;
}
// 4. 输出结果
// 判断c是否产生进位
if(c[lc + 1] != 0) lc++;
for(int i = 1; i <= lc; ++i)
{
cout << c[lc - i + 1];
}
cout << endl;
return 0;
}
高精度减法
要点: 逐位相减,处理退位
-
题目描述 (Description)
输入两个大整数a,b,输出他们的差。(1<=a,b<=10^100) -
输入格式(Format Input)
输入两个大非负整数a和b。(1<=a,b<=10^100) -
输出格式(Format Output)
输出a减b的差。 -
样例(Sample)
输入样例1 (Sample Input 1)
复制
35 45
输出样例1 (Sample Output 1)
-10
#include <bits/stdc++.h>
using namespace std;
char aa[10010], bb[10010]; // 初始数据
int c[10010], a[10010], b[10010], la, lb, lc;
int main()
{
// 1. 初始化
memset(a, 0, sizeof(a));
memset(b, 0, sizeof(b));
memset(c, 0, sizeof(c));
scanf("%s %s", aa + 1, bb + 1); // customize:从下标1开始保存数据
la = strlen(aa + 1);
lb = strlen(bb + 1);
// 2. 位数对其(高位在后,低位在前)
for(int i = 1; i <= la; i++)
a[i] = aa[la - i + 1] - '0';
for(int i = 1; i <= lb; i++)
b[i] = bb[lb - i + 1] - '0';
// 3. 判断a和b的大小
bool flag = 1; // 使用flag表示+/-
if(la > lb) flag = 1;
else if(la < lb) flag = 0;
else
{
// la = lb
for(int i = la; i > 0; i--)
{
if(a[i] > b[i])
{
flag = 1;
break;
}
else if(a[i] < b[i])
{
flag = 0;
break;
}
// 若a和b一直相等,则flag保持不变,flag = 1
}
}
// 4. 减法计算,结果保存到数组c中
// 判断正负
if(flag == 0)
{
cout << "-";
swap(a, b); //交换数组 -- 保证 a > b
swap(la, lb); // 交换数组长度
}
// 计算数组c的长度 -- max(la, lb)
lc = max(la, lb);
for(int i = 1; i <= lc; i++)
{
// 逐位计算 a-b
c[i] = c[i] + a[i] - b[i];
if(c[i] < 0)
{
c[i] += 10; // 小 -大,借位
a[i + 1]--; // 高位 - 1
}
}
// 4. 输出结果
// 退位 消除前导0
while(c[lc] == 0 && lc > 1)
lc--; // 从最高位开始,直到找到第一个不为0的数组元素 或结果为0
for(int i = lc; i > 0; i--)
{
cout << c[i];
}
cout << endl;
return 0;
}
高精度乘法
要点:
#include <bits/stdc++.h>
using namespace std;
char ca[110], cb[110]; // 原始数据
int a[110], b[110], c[210]; // 处理后的数据
int main()
{
// 1. 初始化 赋值
memset(a, 0, 110);
memset(b, 0, 110);
memset(c, 0, 110);
cin >> ca >> cb;
int la = strlen(ca);
int lb = strlen(cb);
// 2. 位数对其(int)
for(int i = 0; i < la; ++i)
a[la - i] = ca[i] - '0';
for(int i = 0; i < lb; ++i)
b[lb - i] = cb[i] - '0';
// 3. 乘法计算
int lc = la + lb - 1; // lc最多位数为 la + lb 位
for(int i = 1; i <= la; ++i)
{
// a从个位开始逐一和b的每一位相乘,最多影响2位
for(int j = 1; j <= lb; ++j)
{
// a[i] * b[j] 会影响c[i + j]和c[i + j - 1]两位
c[i + j - 1] += a[i] * b[j];
c[i + j] += c[i + j - 1] / 10;
c[i + j - 1] %= 10;
}
}
if(c[lc + 1]) lc++;
while(c[lc] == 0 && lc > 1) lc--;
for(int i = lc; i > 0; --i) cout << c[i];
return 0;
}
高精度除法(高精度除以低精度)
要点: 模拟短除法。
#include <bits/stdc++.h>
using namespace std;
char aa[110];
int a[110], c[110], b, x = 0; // x -- 余数
int main()
{
// 1. 初始化
memset(a, 0, sizeof(a));
memset(c, 0, sizeof(c));
scanf("%s %d", aa + 1, &b);
int la = strlen(aa + 1);
// 转换放入int型数组a中
for(int i = 1; i <= la; i++)
a[i] = aa[i] - '0';
// 2. 除法运算,将结果保存在数组c中
for(int i = 1; i <= la; i++)
{
c[i] = (x * 10 + a[i]) / b; // 存储一位结果(高-->低)
x = (x * 10 + a[i]) % b; // 更新余数
}
// 3. 去除前导0,保留个位数
int lc = 1;
// a / b结果最多可能有最多可能有la位,如果到la-1位都为0,则保留最后一位
while(c[lc] == 0 && lc < la) lc++;
// 4. 输出结果
// 从lc开始往后输出,直到la(个位)
for(int i = lc; i <= la; i++)
cout << c[i];
return 0;
}