从第 (n-1) 个格雷码导出第 n 个格雷码
Deriving nth Gray code from the (n-1)th Gray Code
有没有办法通过对第(n-1)个格雷码进行位运算,用第(n-1)个格雷码推导出4位第n个格雷码?
例如第4个格雷码是0010,现在我想通过对0010进行位运算得到第5个格雷码0110
下面的呢?
t1 := XOR(g0, g1)
b0 := !XOR(g0, g1, g2, g3)
b1 := t1 & g2 & g3 + !t1 & !g2 & !g3
b2 := t1 & g2 & !g3
b3 := t1 & !g2 & !g3
n0 := XOR(b0, g0)
n1 := XOR(b1, g1)
n2 := XOR(b2, g2)
n3 := XOR(b3, g3)
当前格雷码字为g3 g2 g1 g0
,下一个码字为n3 n2 n1 n0
。 b3 b2 b1 b0
是翻转或不翻转码字中的一位以前进到后续码字的四位。相邻码字之间只改变一位。
也许是 "cheating" 但您可以将查找 table 打包成一个 64 位常量值,如下所示:
0000 0 -> 1
0001 1 -> 3
0011 3 -> 2
0010 2 -> 6
0110 6 -> 7
0111 7 -> 5
0101 5 -> 4
0100 4 -> C
1100 C -> D
1101 D -> F
1111 F -> E
1110 E -> A
1010 A -> B
1011 B -> 9
1001 9 -> 8
1000 8 -> 0
FEDCBA9876543210 nybble order (current Gray code)
| |
V V
EAFD9B80574C2631 next Gray code
然后您可以使用班次和掩码来执行查找(取决于您的语言):
int next_gray_code(int code)
{
return (0xEAFD9B80574C2631ULL >> (code << 2)) & 15;
}
或者,您可以使用从 Gray to binary 转换的公式,增加值,然后从二进制转换为格雷,即 n xor (n / 2):
int next_gray_code(int code)
{
code = code ^ (code >> 2);
code = code ^ (code >> 1);
code = (code + 1) & 15;
return code ^ (code >> 1);
}
有没有办法通过对第(n-1)个格雷码进行位运算,用第(n-1)个格雷码推导出4位第n个格雷码?
例如第4个格雷码是0010,现在我想通过对0010进行位运算得到第5个格雷码0110
下面的呢?
t1 := XOR(g0, g1)
b0 := !XOR(g0, g1, g2, g3)
b1 := t1 & g2 & g3 + !t1 & !g2 & !g3
b2 := t1 & g2 & !g3
b3 := t1 & !g2 & !g3
n0 := XOR(b0, g0)
n1 := XOR(b1, g1)
n2 := XOR(b2, g2)
n3 := XOR(b3, g3)
当前格雷码字为g3 g2 g1 g0
,下一个码字为n3 n2 n1 n0
。 b3 b2 b1 b0
是翻转或不翻转码字中的一位以前进到后续码字的四位。相邻码字之间只改变一位。
也许是 "cheating" 但您可以将查找 table 打包成一个 64 位常量值,如下所示:
0000 0 -> 1
0001 1 -> 3
0011 3 -> 2
0010 2 -> 6
0110 6 -> 7
0111 7 -> 5
0101 5 -> 4
0100 4 -> C
1100 C -> D
1101 D -> F
1111 F -> E
1110 E -> A
1010 A -> B
1011 B -> 9
1001 9 -> 8
1000 8 -> 0
FEDCBA9876543210 nybble order (current Gray code)
| |
V V
EAFD9B80574C2631 next Gray code
然后您可以使用班次和掩码来执行查找(取决于您的语言):
int next_gray_code(int code)
{
return (0xEAFD9B80574C2631ULL >> (code << 2)) & 15;
}
或者,您可以使用从 Gray to binary 转换的公式,增加值,然后从二进制转换为格雷,即 n xor (n / 2):
int next_gray_code(int code)
{
code = code ^ (code >> 2);
code = code ^ (code >> 1);
code = (code + 1) & 15;
return code ^ (code >> 1);
}