转移大数字

时间:2012-05-10 02:39:28

标签: c++ linked-list bit-manipulation biginteger shift

X = 712360810625491574981234007851998使用链接列表表示,每个节点都是unsigned int

linked list of 712360-810625491-574981234-007851998

除了 X << 8 X << 591之外,还有一种快速的方法吗 X * 2^8 X * 2^591

2 个答案:

答案 0 :(得分:1)

任意位数的位移都非常容易。只记得将溢出的位移到下一个元素。这就是全部

下面是左移3个例子

uint64_t i1, i2, i3, o1, o2, o3; // {o3, o2, o1} = {i3, i2, i1} << 3;

o3 = i3 << 3 | i2 >> (32 - 3);
o2 = i2 << 3 | i1 >> (32 - 3);
o1 = i1 << 3;

类似于右移,只是反向迭代。

编辑:

似乎你使用基数10 9 作为你的大数字,所以二元移位在这里适用。在基础B中“移位”左/右N个数字相当于分别将数字乘以B N 和B -N 。你不能用十进制进行二进制移位,反之亦然

如果你没有改变你的基础,那么你只有一个解决方案,那就是将数字乘以2 591 。如果你想像二进制一样移动你必须改为base that is a power of 2类似基数2 32 或基数2 64

一般解决方案是这样的,肢体存储在小端,每个数字都在基数2 CHAR_BIT * sizeof(T)

template<typename T>
void rshift(std::vector<T>& x, std::size_t shf_amount) // x >>= shf_amount
{
    constexpr std::size_t width = CHAR_BIT*sizeof(T);
    if (shf_amount > width)
        throw;

    const std::size_t shift     = shf_amount % width;
    const std::size_t limbshift = shf_amount / width;

    std::size_t i = 0;
    for (; i < x.size() - limbshift - 1; ++i)
        x[i] = (x[i + limbshift] >> shift) | (x[i + 1 + limbshift] << (width - shift));
    x[i++] = x[i + limbshift] >> shift;
    for (; i < x.size() ; ++i)
        x[i] = 0;
}

此外,从标签开始,您可能会使用链接列表来存储由于元素在内存空间周围散布而无法缓存的肢体,并且由于而浪费了大量内存下一个指针。事实上,你不应该在大多数现实生活中使用链表

答案 1 :(得分:0)

我认为,如果使用64位整数,代码应为

    o3 = i3 << 3 | i2 >> (32 - 3);
    .....