当一个数非常大的时候,c++无法直接将两个整形数据相加,这个时候需要用字符串来过渡一下。
1.高精度加法:
#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
int a[100001], b[100001], c[100001];
int main()
{
string x, y;
int m, n;
cin >> x >> y;//输入字符串
m = x.size();
n = y.size();//两个字符串的长度
for (int i = 0; i < m; i++)
{
a[m - i] = x[i]-'0';//将x字符串中的每一位转化为整形存放到a数组
}
for (int i = 0; i < n; i++)
{
b[n - i] = y[i]-'0';//将y字符串中的每一位转化为整形存放到b数组
}
int p = max(m, n);//因为要保证所有的数相加完,所以必须是最大值
for (int i = 1; i <= p; i++)
{
c[i] += a[i] + b[i];
c[i + 1] = c[i] / 10;
c[i] = c[i] % 10;
}//这个地方由此实现加法的运算
if (c[p + 1] > 0)p++;//有可能在最后出现相加的数字大于十,所以要p再加上1
for (int i = p; i >= 1; i--)
{
cout << c[i];
}
cout << endl;
return 0;
}
2.高精度减法
#include<iostream>
#include<cstring>
using namespace std;
int MAXN = 100005; //根据题目的最大值。+4为了防止A+B出现进位
char s1[100005] = {};//存储字符串
char s2[100005] = {};//存储字符串
char tmp[100005] = {};//交换用字符串
int a[100005] = {};//存储加数A
int b[100005] = {};//存储加数B
int c[100005] = {};//存储和B
int lena;
int lenb;
int main() {
cin >> s1 >> s2;//读入字符串
lena = strlen(s1);
lenb = strlen(s2);
//判断最终的结果符号
if ((lena < lenb) || (lena == lenb && strcmp(s1, s2) < 0)) {//说明前面的那个数小于后面的那个数
//被减数小于减数,结果为负数
printf("-");
//交换数据
strcpy(tmp, s1);
strcpy(s1, s2);
strcpy(s2, tmp);
//更新长度数据
lena = strlen(s1);
lenb = strlen(s2);
}
//将字符串写入到数组A中
for (int i = 0; i < lena; i++) {
//倒序写入
a[i] = s1[lena - i - 1] - '0';
}
//将字符串写入到数组B中
for (int i = 0; i < lenb; i++) {
//倒序写入
b[i] = s2[lenb - i - 1] - '0';
}
//模拟竖式减法
for (int i = 0; i < lena; i++) {
if (a[i] < b[i]) {
//有借位
a[i + 1]--;
a[i] += 10;
}
c[i] = a[i] - b[i];
}
//删除前导零
while(0 == c[i] && lena > 1) {
//注意要有 lena>1 这个条件。考虑特殊情况,加法结果为 00,我们实际要输出 0。
lena--;
}
//逆序打印输出
for (int i = lena - 1; i >= 0; i--) {
printf("%d", c[i]);
}
printf("\n");
return 0;
}
3.高精度乘法
#include<iostream>
#include<cstring>
#define N 10005
using namespace std;
char s1[N];
char s2[N];
int a[N];
int b[N];
int s[N * 2];
int main()
{
cin >> s1 >> s2;
int len1 = strlen(s1);
int len2 = strlen(s2);//计算两个数的长度
for (int i = 0; i < len1; i++)
a[i] = s1[len1 - i - 1] - '0';//转换为整型这是老套路了
for (int i = 0; i < len2; i++)
b[i] = s2[len2 - i - 1] - '0';//同上
int p = 0;
for (int i = 0; i < len1; i++)
{
p = 0;
for (int j = 0; j < len2; j++) {
s[i + j] += a[i] * b[j] + p;
p = s[i + j] / 10;
s[i + j] %= 10;
}
s[i + len2] += p;
}
int q = len1 + len2;
while (q > 0 && s[q] == 0)q--;//删除前面可能出现的0
for (int i = q; i >= 0; i--)
cout << s[i];
cout << endl;
return 0;
}
4.高精度除法:
#include<iostream>
#include<cstring>
using namespace std;
char a1[10001];
long long b,c[10001],d,a[10001],len,lenc;
int main ()
{
cin >>a1 >>b;//读入被除数和除数
len=strlen(a1);//把被除数的位数存在len里
for (int i=1;i<=len;i++)a[i]=a1[i-1]-'0';//将被除数一位一位放入a数组
for (int i=1;i<=len;++i)//这一个循环是关键,将被除数一位一位除以除数,不过除,向下
{ //一位借位,d为余数,c数组为商
c[i]=(d*10+a[i])/b;
d=(d*10+a[i])%b;
}
lenc=1;
while (c[lenc]==0&&lenc<len)lenc++;//整理位数,删除前导0
for (int i=lenc;i<=len;++i)cout <<c[i]; //输出结果
return 0;
}
高精度除法目前还有一些问题。