使用XOR交换单个位

我正在读这篇文章用Xor交换单个位来交换给定数字的位。

作为* 交换比特范围的一个例子, 假设我们有b = 00101111(以二进制表示),我们想要交换从i = 1开始的n = 3个连续比特(右边的第二个比特)和3个连续比特从j = 5开始; 结果将是r = 11100011(二进制)。 *但我无法理解它是如何工作的。
鉴于代码是

unsigned int i, j; // positions of bit sequences to swap unsigned int n; // number of consecutive bits in each sequence unsigned int b; // bits to swap reside in b unsigned int r; // bit-swapped result goes here unsigned int x = ((b >> i) ^ (b >> j)) & ((1U << n) - 1); // XOR temporary r = b ^ ((x << i) | (x << j)); 

请任何人清楚我这个代码是如何工作的。

让我们分步执行:(b >> i)和(b >> j)将要交换的位移动到第一位。

((b >> i)^(b >> j))然后对它们进行异或。

((1U << n) - 1)这个表达式只是数字1111 ... 1 n次(二进制)

所以总共x是XOR的结果,所有其他位都是0。

(x << i)和(x << j)将位移回正确的位置。

with((x << i)|(x << j))在结果中设置在任一个中设置的所有位。

并且b ^((x << i)|(x << j))意味着我们使用两个部分的XOR'd位对原始进行异或。 注意x ^ x ^ y = y所以因为在两个部分中原始在xor中出现两次,而第二部分只出现一次,我们得到位交换。

好吧,它正在使用移位来限制每个操作所影响的比特(即,将其他人拖出图片以完成工作,并且仅与我们关心的人一起操作)。 作为其中的一部分,它用xor翻转那些位,将它们移回,然后通过与原始x-oring将它们翻转回原始位。 ……因为那就像泥一样清楚……

例如。

 XX...XX001 ^ XX..XX111 = XX..XX110 (xor the 2 sequences together + trash bits) XX..XX110 & 0...0111 = 110 (keep only those bits we care about) 00101111 ^ 11001100 = 11100011 (and magic!)