使用XOR交换单个位

时间:2012-09-11 06:11:48

标签: c binary

我正在阅读this article用Xor交换单个位以交换给定数字的位。

作为* 交换比特范围的一个例子,假设我们有b = 00101111(用二进制表示),我们想要交换从i = 1开始的n = 3个连续比特(右边的第二个比特)和从j = 5开始的3个连续位;结果将是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));

请任何人清楚我这段代码是如何运作的。

2 个答案:

答案 0 :(得分:4)

让我们分步骤: (b&gt;&gt; i)和(b&gt;&gt; j)将要交换的位移动为第一位。

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

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

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

(x <&lt;&lt;&lt;&lt;&lt;&lt;&lt;&quot; j)将这些位移回正确的位置。

with((x <&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&quot;&quot; / j))在结果中设置在任一个中设置的所有位。

并且b ^((x

答案 1 :(得分:3)

嗯,它正在使用移位来限制每个操作所影响的位(即,将其他位置移出图像以完成工作,并且仅与我们关心的那些一起操作)。作为其中的一部分,它用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!)