将跨越多个无符号长整型表示的两个二进制数相加的高效算法

问题描述 投票:0回答:1

我想在这个特定的框架中对两个二进制数求和,我将参考C++的编码语法。 64 个二进制数被编码为无符号 long long int 向量。

vector<unsigned long long int> a;

其中 v[j] 的第 i 位等于第 i 个数的第 j 位,i = 0, ..., 64-1。

现在让我们考虑两个 64 位数字的集合

vector<unsigned long long int> a, b;

我想通过按位运算,将a中编码的64个数字与b中编码的64个数字一次性求和。例如,我想将a中编码的第0个数字与b中编码的第0个数字相加,将a中编码的第1个数字与b中编码的第1个数字相加,等等,然后写入结果变成一个

vector<unsigned long long int> c;

最快的方法是什么?我似乎记得必须使用二叉树结构,但我不确定。

c++ algorithm binary bit-manipulation
1个回答
0
投票

添加一对转置整数(每个逻辑整数物理存储在位矩阵的列中)可以像这样完成:

#include <cstdint>
#include <vector>
#include <cstddef>

using std::uint64_t;
using std::size_t;

std::vector<uint64_t> add_transposed_integers(
    const std::vector<uint64_t> &a,
    const std::vector<uint64_t> &b)
{
    size_t n = a.size();
    std::vector<uint64_t> c(n);

    uint64_t carry = 0;
    for (size_t i = 0; i < n; i++) {
        uint64_t sum = (a[i] ^ b[i]) ^ carry;
        carry = (a[i] & b[i]) | (carry & (a[i] ^ b[i]));
        c[i] = sum;
    }

    return c;
}

这里的按位逻辑只是纹波进位加法。

我假设

a
b
c
都应该具有相同的位数(这意味着:它们的向量都具有相同的长度)。如果不是这样,您可以轻松地进行一些修改。

我并不认为这是最快的方法,但让它更快并不容易。例如,您可能会考虑 SIMD,但进位传播确实很奇怪,您需要一些更高级的加法算法,例如 Kogge-Stone,它可以支持一些并行性,但总共会花费更多的操作。

© www.soinside.com 2019 - 2024. All rights reserved.