任意位数的位移非常容易。只要记住将溢出的位移至下一个元素。就这样
下面是左移 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;
与右移类似,只是反向迭代。
Edit:
It seems that you're using base 109 for your large number, so binary shifting does not apply here. "Shifting" left/right N digits in a base B is equivalent to multiplying the number by BN and B-N respectively. You can't do binary shift in decimal and vice versa
If you don't change your base then you have only one solution, that's multiplying the number by 2591. If you want to shift like in binary you must change to a base that is a power of 2 https://stackoverflow.com/q/23840565/995714 like base 232 or base 264
A general solution to shift would be like this, with the limbs ("digits" or each small word unit in a big integer, in arbitrary-precision arithmetic term) stored in little-endian and each digit is in base 2CHAR_BIT*sizeof(T)
template<typename T,
class = typename std::enable_if<std::is_unsigned<T>::value>::type>
void rshift(std::vector<T>& x, std::size_t shf_amount) // x >>= shf_amount
{
// The number of bits in each limb/digit
constexpr std::size_t width = CHAR_BIT*sizeof(T);
if (shf_amount > width)
throw; // or zero out the whole vector for saturating shift
// Number of limbs to shift
const std::size_t limbshift = shf_amount / width;
// Number of bits to shift in each limb
const std::size_t shift = shf_amount % width;
std::size_t i = 0;
// Shift the least significant bits
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;
i++;
// Zero out the most significant bits
for (; i < x.size() ; ++i)
x[i] = 0;
}
此外,从标签来看,您可能使用链接列表来存储肢体,由于元素分散在内存空间中,该链接列表对缓存不友好,并且由于next指针。实际上,在这种情况下,指针和内存分配使用的内存甚至比用于存储数据位的内存还要大。事实上,在大多数现实生活问题中你不应该使用链表
- Bjarne Stroustrup 说我们必须避免链表 https://stackoverflow.com/q/34170566/995714
- 为什么你永远、永远、永远不要再在你的代码中使用链表 https://kjellkod.wordpress.com/2012/02/25/why-you-should-never-ever-ever-use-linked-list-in-your-code-again/
- 数字运算:为什么你不应该再在代码中使用链表 https://www.codeproject.com/articles/340797/number-crunching-why-you-should-never-ever-ever-us
- Bjarne Stroustrup:为什么应该避免使用链表 https://www.reddit.com/r/programming/comments/25xpre/bjarne_stroustrup_why_you_should_avoid_linked/
- 列表是邪恶的吗?——Bjarne Stroustrup https://isocpp.org/blog/2014/06/stroustrup-lists