给定一个无符号整数,很容易交换每个偶数位和奇数位。这可以推广到交换每个偶数和奇数n位吗?

Given an unsigned integer, it's easy to swap every even and odd bit. Can this be generalized to swapping every even and odd n bits?

本文关键字:交换 位吗 一个 无符号整数 很容易      更新时间:2023-10-16

在n = 1的情况下,如果我们有一个未签名的32位整数i,则交换整数为

((i & 0xaaaaaaaa) >> 1) | ((i & 0x55555555) << 1)

n = 2

((i & 0xcccccccc) >> 2) | ((i & 0x33333333) << 2)

当n = 4

((i & 0xf0f0f0f0) >> 4) | ((i & 0x0f0f0f0f) << 4)

等等。

n如果n是2的任意能力?...而且,假设我是一个任意的128位整数,而不是一个32位整数,所以我们有7个案例,而不是5个案例?

我怀疑有一种方法可以概括给定n的过程(即,从n中生成掩码(,很高兴拥有它向上(例如,实现某些加密哈希函数 - 例如JH(。

想到的明显方法是循环循环潜在的面具,在n较大的情况下,迭代率较少,但我宁愿有一种可以在恒定时间内完成操作较少的方法。

例如,适用于32位整数的东西:

uint32_t mask = 0; submask = (2n) - 1;
for (uint32_t index = 0; index < 32; index += 2n)
{
    mask |= submask;
    submask <<= 2n;
}

是否有更好的方法来生成该掩码(理想情况下没有循环(?

编辑:我只是想到我而不是

((i & 0xaaaaaaaa) >> 1) | ((i & 0x55555555) << 1)

你可以做

((i & 0xaaaaaaaa) >> 1) | ((i << 1) & 0xaaaaaaaa)

它允许完全不需要使用倒面膜。偶然有人会查看此参考,这可能很方便。

我认为这种方法更有效。您可以存储或生成第一个掩码值。如果我的C 不太正确,请原谅我,我更像是PHP/JavaScript程序员。此代码将依次生成所有掩码,因此您可以将它们保存到一个数组中,或者在您想要的掩码处停止循环:

uint32_t mask = 0xffffffff; // can perhaps use int32 and -1?
for (uint32_t i = 4; i >= 0; i--)  {
   mask ^= mask >> (1 << i);
   cout << mask;
}