高精度(加减乘除)

当一个数非常大的时候,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;
}

高精度除法目前还有一些问题。

上一篇:RITSEC CTF2021 Forensics1597题解记录


下一篇:UVa 1597