Skip to content

大数的加减乘除

自然常数 e(自然对数的底数):2.7182818284590452353602874

大数加法:

cpp
string add(string a, string b)
{
    string s;
    reverse(a.begin(), a.end());
    reverse(b.begin(), b.end());
    int i = 0;
    int m, k = 0;
    while(a[i] && b[i])
    {
        m = a[i] - '0' + b[i] - '0' + k;
        k = m / 10;
        s += (m % 10 + '0');
        i++;
    }
    if(i == a.size())
    {
        while(i != b.size())
        {
            m = k + b[i] - '0';
            k = m / 10;
            s += m % 10 + '0';
            i++;
        }
        if(k) s += k + '0';
    }
    else if(i == b.size())
    {
        while(i != a.size())
        {
            m = k + a[i] - '0';
            k = m / 10;
            s += m % 10 + '0';
            i++;
        }
        if(k) s += k + '0';
    }
    reverse(s.begin(), s.end());
    return s;
}

比较短的:

cpp
string sum(string s1,string s2)
{
    if(s1.length()<s2.length())
    {
        string temp=s1;
        s1=s2;
        s2=temp;
    }
    int i,j;
    for(i=s1.length()-1,j=s2.length()-1; i>=0; i--,j--)
    {
        s1[i]=char(s1[i]+(j>=0?s2[j]-'0':0));   //注意细节
        if(s1[i]-'0'>=10)
        {
            s1[i]=char((s1[i]-'0')%10+'0');
            if(i) s1[i-1]++;
            else s1='1'+s1;
        }
    }
    return s1;
}

大数减法:

cpp
#include<cstdio>
#include<cstring>
#include<string>
#include<iostream>
using namespace std;
string sub(string a, string b)
{
    int i, j, k, s, flag = 1;
    int tmpa[10000], tmpb[10000], c[10000];
    string ans;
    if(a.size() < b.size() || (a.size() == b.size() && a.compare(b) < 0))
    {
        string tmp = a;
        a = b;
        b = tmp;
        flag = 0;
    }
    while(a.length() > b.length()) b = '0' + b;
    int len = a.length();
    for(i = 0; i < len; i++)
    {
        tmpa[i] = a[i] - '0';
        tmpb[i] = b[i] - '0';
    }
    for(i = len - 1; i >= 0; i--)
    {
        if(tmpa[i] >= tmpb[i])
            c[i] = tmpa[i] - tmpb[i];
        else
        {
            c[i] = 10 + tmpa[i] - tmpb[i];
            tmpa[i-1]--;
        }
    }
    for(i = 0; i < len - 1; i++)
        if(c[i] != 0)
            break;
    for(j = i; j < len; j++)
        ans = ans + (char)(c[j] + '0');
    if(!flag)
        ans = '-' + ans;
    return ans;
}
int main()
{
    string a, b;
    while(cin >> a >> b)
    {
        cout << sub(a, b) << endl;
    }
    return 0;
}

大整数乘以小整数(可以用整型变量表示的整数)

cpp
string multi(string a, int k)
{
    if(k == 0) return "0";
    int len = a.length(), carry = 0;
    reverse(a.begin(), a.end());
    for(int i = 0; i < len; i++)
    {
        int s = (a[i] - '0') * k + carry;
        a[i] = s % 10 + '0';
        carry = s / 10;
    }
    while(carry != 0)
    {
        a = a + (char)(carry % 10 + '0');
        carry /= 10;
    }
    reverse(a.begin(), a.end());
    return a;
}

两个不含前导0的大整数相乘

cpp
string multi_string_int(string a, int k)
{
	if(k == 0) return "0";
	int len = a.length(), carry = 0;
	reverse(a.begin(), a.end());
	for(int i = 0; i < len; i++)
	{
		int s = (a[i] - '0') * k + carry;
		a[i] = s % 10 + '0';
		carry = s / 10;
	}
	while(carry != 0)
	{
		a = a + (char)(carry % 10 + '0');
		carry /= 10;
	}
	reverse(a.begin(), a.end());
	return a;
}
string add(string a, string b)
{
	string s;
	reverse(a.begin(), a.end());
	reverse(b.begin(), b.end());
	int i = 0;
	int m, k = 0;
	while(a[i] && b[i])
	{
		m = a[i] - '0' + b[i] - '0' + k;
		k = m / 10;
		s += (m % 10 + '0');
		i++;
	}
	if(i == a.size())
	{
		while(i != b.size())
		{
			m = k + b[i] - '0';
			k = m / 10;
			s += m % 10 + '0';
			i++;
		}
		if(k) s += k + '0';
	}
	else if(i == b.size())
	{
		while(i != a.size())
		{
			m = k + a[i] - '0';
			k = m / 10;
			s += m % 10 + '0';
			i++;
		}
		if(k) s += k + '0';
	}
	reverse(s.begin(), s.end());
	return s;
}
string multi_string_string(string a, string b)
{
	string ans = "";
	for(int i = a.size() - 1; i >= 0; i--)
	{
		string tmp = multi_string_int(b, a[i] - '0');
		for(int j = 0; j < a.size() - 1 - i; j++)
			tmp += '0';
		ans = add(ans, tmp);
	}
	return ans;
}

求大整数除以一个小整数的商

cpp
string division(string str, int x)
{
    string ans = "";
    int len = str.length();
    int y = 0;
    for(int i = 0; i < len; i++)
    {
        ans += char((y * 10 + (str[i] - '0')) / x + '0');
        y = (y * 10 + (str[i] - '0')) % x;
    }
    while(*(ans.begin()) == '0' && ans.size() > 1) ans.erase(ans.begin());
    return ans;
}

求一个大整数对一个小整数的余数

cpp
int Mod(string str, int x)
{
    int len = str.length();
    int y = 0;
    for(int i = 0; i < len; i++)
        y = (y * 10 + (str[i] - '0')) % x;
    return y;
}

大数阶乘(n<=10000)

cpp
#include<stdio.h>
#include<string.h>
const int maxn=40000;  /*数组不能太小,小了存不下*/
int a[maxn];
int main()
{
    int i,j,n;
    while(~scanf("%d",&n))
    {
        memset(a,0,sizeof(a));
        a[0]=1;
        for(i=2; i<=n; i++)
        {
            int c=0;  /*保存进位*/
            for(j=0; j<maxn; j++)
            {
                int s=a[j]*i+c;
                a[j]=s%10;
                c=s/10;
            }
        }
        for(j=maxn-1; j>=0; j--) /*去掉前导零*/
            if(a[j])
                break;
        for(i=j; i>=0; i--)
            printf("%d",a[i]);
        printf("\n");
    }
    return 0;
}

__int128的输入输出模板

cpp
#include <bits/stdc++.h>
using namespace std;

void scan(__int128 &x)//输入
{
    x = 0;
    int f = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9')
    {
        if(ch == '-') f = -1;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9')
    {
        x = x*10 + ch-'0';
        ch = getchar();
    }
    x *= f;
}

void print(__int128 x)//输出
{
    if(x < 0)
    {
        x = -x;
        putchar('-');
    }
    if(x > 9) print(x/10);
    putchar(x%10 + '0');
}

int main()
{
    __int128 a, b;
    scan(a);
    scan(b);
    print(a + b);
    puts("");
    print(a*b);
    return 0;
}

基于 MIT 协议发布 · 使用 VitePress 构建