首页 > 试题广场 >

高精度整数加法

[编程题]高精度整数加法
  • 热度指数:147160 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
\hspace{15pt}输入两个超大整数 a,b,计算它们的和。

输入描述:
\hspace{15pt}输入两个整数 a,b \left(0 \leqq a,b \lt 10^{10\,000}\right)


输出描述:
\hspace{15pt}输出一个整数,表示 ab 的和。
示例1

输入

9876543210
1234567890

输出

11111111100
只学过python的人肯定想问:这题到底妖姬吧干啥
发表于 2025-05-19 15:42:38 回复(0)
这道题对python而言是直接秒杀——python内置了这个大整数的计算支持。
import sys

inputs = []
for line in sys.stdin:
    a = line.split()
    inputs.append(a)

m, n = int(inputs[0][0]), int(inputs[1][0])
print(m+n)
但是,如果要C++的话,就会超级蛋疼。因为:C++没!有!内!置!这!个!
然后我就找到chatgpt,让它手搓了一个超大整数的处理器。
#include <iostream>
#include <vector>
#include <string>
#include <cmath>
#include <cstdlib>
#include <algorithm>

using namespace std;

class InfiniteInt {
public:
    // 默认构造函数
    InfiniteInt() : digits(0) {}

    // 将十进制字符串转换为无限长整数
    InfiniteInt(const string& str) {
        // 计算需要多少个 byte:
        // 根据十进制位数 d,最大数为 10^d - 1,
        // 需要的二进制位数至少为 ceil(d * log2(10)),
        // 转换成 byte 数量即为 (bits/8) + 1(这里使用整除,保证足够存储)
        double d = static_cast<double>(str.length());
        this->digits = (static_cast<int64_t>(std::ceil(d * std::log2(10))) / 8) + 1;
        
        // 分配内存,每个 byte 用 malloc(1) 得到一个 char*,初值设为 0
        for (int32_t i = 0; i < this->digits; i++) {
            char* byte = reinterpret_cast<char*>(malloc(1));
            *byte = 0;
            numbers.push_back(byte);
        }
        
        // 从字符串中转换,每次乘以 10,再加上当前数字
        // 这里采用的是“高位先”的处理:依次处理字符串中的每个字符
        for (char ch : str) {
            int digitVal = ch - '0';
            
            // 先将当前数乘以 10
            int carry = 0;
            for (int i = 0; i < this->digits; i++) {
                int tmp = (static_cast<unsigned char>(*numbers[i]) * 10) + carry;
                *numbers[i] = tmp & 0xFF;
                carry = tmp >> 8;  // 除以 256 的商作为进位
            }
            // 然后加上当前的数字
            carry = digitVal;
            for (int i = 0; i < this->digits; i++) {
                int tmp = static_cast<unsigned char>(*numbers[i]) + carry;
                *numbers[i] = tmp & 0xFF;
                carry = tmp >> 8;
            }
        }
    }
    
    // 析构函数:释放内部申请的内存
    ~InfiniteInt() {
        for (char* byte : numbers) {
            free(byte);
        }
    }
    
    // 加法运算:返回一个新的 InfiniteInt 对象(this + other)
    InfiniteInt operator+(const InfiniteInt& other) const {
        // 取较大的字节数,再加一位可能的进位
        int64_t maxDigits = std::max(this->digits, other.digits);
        InfiniteInt result;
        result.digits = maxDigits + 1;
        for (int i = 0; i < result.digits; i++) {
            char* byte = reinterpret_cast<char*>(malloc(1));
            *byte = 0;
            result.numbers.push_back(byte);
        }
        
        int carry = 0;
        // 按低位到高位依次相加
        for (int i = 0; i < result.digits; i++) {
            int a = (i < this->digits) ? static_cast<unsigned char>(*this->numbers[i]) : 0;
            int b = (i < other.digits) ? static_cast<unsigned char>(*other.numbers[i]) : 0;
            int sum = a + b + carry;
            *result.numbers[i] = sum & 0xFF;
            carry = sum >> 8;
        }
        
        // 如果最高字节为 0,则可以减少一位(但 0 本身应保留至少 1 个 byte)
        if (result.digits > 1 && static_cast<unsigned char>(*result.numbers[result.digits - 1]) == 0) {
            free(result.numbers[result.digits - 1]);
            result.numbers.pop_back();
            result.digits--;
        }
        
        return result;
    }
    
    // 输出运算符重载,将 InfiniteInt 转换为十进制字符串输出
    friend ostream& operator<<(ostream& os, const InfiniteInt& num) {
        // 将内部表示(little-endian)转换为 big-endian 存储到一个 vector 中
        vector<int> temp;
        for (int i = num.digits - 1; i >= 0; i--) {
            temp.push_back(static_cast<unsigned char>(*num.numbers[i]));
        }
        
        // 特殊情况:数值为 0
        if (temp.size() == 0 || (temp.size() == 1 && temp[0] == 0)) {
            os << "0";
            return os;
        }
        
        string result;
        // 使用长除法算法:不断除以 10,记录余数
        while (!(temp.size() == 1 && temp[0] == 0)) {
            int remainder = 0;
            for (size_t i = 0; i < temp.size(); i++) {
                int current = remainder * 256 + temp[i];
                int quotient = current / 10;
                remainder = current % 10;
                temp[i] = quotient;
            }
            result.push_back('0' + remainder);
            // 去掉前导零
            while (temp.size() > 1 && temp[0] == 0) {
                temp.erase(temp.begin());
            }
        }
        // 余数记录的是低位在前,需要反转得到正确顺序
        reverse(result.begin(), result.end());
        os << result;
        return os;
    }
    
private:
    int64_t digits;           // 内部用多少个 byte 存储
    vector<char*> numbers;    // 存储各个字节,索引 0 为最低有效字节
};
用这个,但这东西的输入只能是字符串。
发表于 2025-02-25 19:31:05 回复(0)
直接加就行了,我以为会有溢出还是精度问题呢
发表于 2025-02-16 22:49:05 回复(0)
python最有用的一集,难绷
发表于 2025-01-19 05:14:46 回复(0)
print(int(input().strip()) + int(input().strip()))

只能说,感谢python
发表于 2024-11-28 18:19:59 回复(0)
num1 = input()
num2 = input()

def adder(n):
    num = 0
    for s in n:
        num = num*10 + int(s)
    return num
print(adder(num1)+adder(num2))
发表于 2024-11-25 15:08:35 回复(0)
# 把输入倒过来方便循环取数字
input_num_first = input()[::-1]
input_num_second = input()[::-1]

# 判断输入长短,分成长短两个
# 98765 12345678
long_num, short_num = "", ""
if len(input_num_first) > len(input_num_second):
    long_num = input_num_first
    short_num = input_num_second
else:
    long_num = input_num_second
    short_num = input_num_first
long_length = len(long_num)
short_length = len(short_num)

# 长度相等部分计算
# 98765 12345
cur = 0
res = ""
for i in range(short_length):
    new_bit = int(long_num[i]) + int(short_num[i]) + cur
    if new_bit >= 10:
        new_bit = str(new_bit - 10)
        cur = 1
    else:
        new_bit = str(new_bit)
        cur = 0
    res += new_bit

# 超出较短长度部分计算
# 678
for i in range(short_length, long_length):
    new_bit = int(long_num[i]) + cur
    if new_bit >= 10:
        new_bit = str(new_bit - 10)
        cur = 1
    else:
        new_bit = str(new_bit)
        cur = 0
    res += new_bit

# 可能存在未考虑的进位,补上
if cur:
    res += str(cur)

# 倒过来就是结果
print(res[::-1])
编辑于 2024-04-15 20:24:56 回复(0)
print(int(input())+int(input()))
#还得是python

发表于 2024-04-11 17:07:17 回复(0)
print(int(input())+int(input()))
人生苦短,我用Python
发表于 2024-03-06 17:12:24 回复(0)
#python可太香了啊
int1 = int(input())
int2 = int(input())
print(int1+int2)
发表于 2024-02-13 11:56:13 回复(0)
a=int(input())
print(a+int(input()))
发表于 2024-02-05 19:10:31 回复(0)
print(int(input()) + int(input()))

发表于 2023-12-08 23:22:07 回复(0)
对于python 不就是白送分吗
print(sum(map(int, [input(), input()])))



发表于 2023-10-13 11:18:21 回复(1)
a = input()
b = input()
try:
    c= int(a)
    d= int(b)
    print(c+d)
except:
    pass

发表于 2023-06-14 09:39:10 回复(0)
# python语言支持大整数,不受位数限制
a=int(input().strip())
b=int(input().strip())
print(a+b)

发表于 2023-04-25 15:58:44 回复(0)
print(int(input().split()[0]) + int(input().split()[0]))

为啥这一句就过了,高精度体现在哪。。。懵的状态
发表于 2023-03-06 23:14:24 回复(1)
s1 = list(map(int,list(reversed(input()))))
s2 = list(map(int,list(reversed(input()))))

cnt = 0
result = []

for i in range(min(len(s1),len(s2))):
    temp = (s1[i]+s2[i]+cnt)%10
    cnt = (s1[i]+s2[i]+cnt)//10
    result.append(temp)

if len(s1)>len(s2):
    for j in range(min(len(s1),len(s2)),len(s1)):
        temp = (s1[j]+cnt)%10
        cnt = (s1[j]+cnt)//10
        result.append(temp)

if len(s1)<len(s2):
    for j in range(min(len(s1),len(s2)),len(s2)):
        temp = (s2[j]+cnt)%10
        cnt = (s2[j]+cnt)//10
        result.append(temp)
if cnt!=0:
    result.append(cnt)
print("".join(list(reversed("".join(list(map(str,result)))))))

发表于 2023-02-24 21:06:12 回复(0)
两行搞定,直接使用Python中自带的库函数decimal,就能实现大数运算

import decimal
from decimal import Decimal as D
s1 = input()
s2 = input()
#设置精度,不然最后一条用例会不通过
decimal.getcontext().prec = 100
print(format((D(s1)+D(s2)),'.0f'))

发表于 2023-02-09 22:14:30 回复(0)