计算第n个灰色代码的公式为:

(n-1) XOR (floor((n-1)/2))
(Source: wikipedia)

我把它编码成:
int gray(int n)
{
  n--;
  return n ^ (n >> 1);
}

有人能解释一下上面的公式是如何工作的,或者可能是它的推导吗?

最佳答案

如果你看二进制计数序列,你会注意到,相邻的代码在最后几位不同(没有空穴),所以如果你异或它们,几个尾随1的模式就会出现。另外,当您右移数字时,xor也将右移:(a xor b)>>n==a>>n xor b>>n。

    N                    N>>1                  gray
 0000           .        0000           .      0000           .
    | >xor = 0001             >xor = 0000           >xor = 0001
 0001          .         0000          .       0001          .
   || >xor = 0011           | >xor = 0001           >xor = 0010
 0010           .        0001           .      0011           .
    | >xor = 0001             >xor = 0000           >xor = 0001
 0011         .          0001         .        0010         .
  ||| >xor = 0111          || >xor = 0011           >xor = 0100
 0100                    0010                  0110

原始的异或结果和移位结果在单个位上是不同的(我用上面的点标记它们)。这意味着,如果你异或它们,你将得到1位模式集。所以,
(A xor B) xor (A>>1 xor B>>1) == (A xor A>>1) xor (B xor B>>1) == gray (A) xor gray (B)

当异或在不同的位上给我们1时,它证明了相邻的码只在一个位上不同,这是我们想要得到的灰色码的主要性质。
所以为了完整性,我们可以证明,n可以从它的n^(n>>1)值恢复:知道第n位代码,我们可以使用xor恢复第n位。
A_[bit n-1] = A_[bit n] xor gray(A)_[bit n-1]

从最大位开始(与0进行异或),这样我们就可以恢复整数。

08-17 00:17