未签名的长期添加和多个操作数

unsigned long long addition with multiple operands

本文关键字:操作数 添加      更新时间:2023-10-16
unsigned long long a = 18446744073709551615
unsigned long long b = 18446744073709551614
unsigned long long c = 18446744073709551613
unsigned long long d = 18446744073709551612
unsigned long long e = 18446744073709551611

我想添加a b c d e并获得结果(64位( crand ,因为它将超过64位。我应该使用BigInteger库吗?有什么更简单的方法可以做这种事情吗?我发现使用BigInteger的大多数东西都很复杂,尽管我的问题似乎很简单,但我找不到非常相似的例子。

如果您只需要添加

#include<cstdint>
#include<limits>
#include<utility>
using std::uint64_t;
std::pair<uint64_t, int> add_with_carry(uint64_t a, uint64_t b)
{
    if(a > std::numeric_limits<uint64_t>::max() - b)
        return {a + b, 1};
    else
        return {a + b, 0};
}
auto [sum, carry] = add_with_carry(a, b);

并扩展到任意链式添加

std::pair<uint64_t, int> add_with_carry(std::pair<uint64_t, int> a)
{
    return a;
}
template<typename... Addends>
std::pair<uint64_t, int> add_with_carry(std::pair<uint64_t, int> a, uint64_t b, Addends... addends)
{
    if(b > std::numeric_limits<uint64_t>::max() - a.first)
        return add_with_carry(std::pair<uint64_t, int>{b + a.first, 1 + a.second}, addends...);
    else
        return add_with_carry(std::pair<uint64_t, int>{b + a.first, a.second}, addends...);
}
template<typename... Addends>
std::pair<uint64_t, int> add_with_carry(uint64_t a, Addends... addends)
{
    return add_with_carry(std::pair<uint64_t, int>{a, 0}, addends...);
}
auto [sum, carry] = add_with_carry(a, b, c, d, e);

可能有一种更优雅的方式可以用折叠表达式实现此功能。

警告:如果在呼叫add_with_carry中有20亿个变量,则可能会溢出int。好运,但是...