Algorithm 格雷码算法(32位或更少)
我最近遇到了格雷码,我一直在努力研究将格雷码转换回二进制(32位或更少)的高效算法 这就是我说的代码。下面是我的问题:Algorithm 格雷码算法(32位或更少),algorithm,gray-code,Algorithm,Gray Code,我最近遇到了格雷码,我一直在努力研究将格雷码转换回二进制(32位或更少)的高效算法 这就是我说的代码。下面是我的问题: 此代码与正常代码(右移1和XOR,直到mask==0)之间有什么区别 为什么专门使用16、8、4、2、1而不是任何其他小于32位的数字 如果我们按照以下相反的方式进行操作,会有什么区别: num = num ^ (num >> 1); num = num ^ (num >> 2); num = num ^ (num >> 4); num =
- 此代码与正常代码(右移1和XOR,直到
)之间有什么区别mask==0
- 为什么专门使用16、8、4、2、1而不是任何其他小于32位的数字
- 如果我们按照以下相反的方式进行操作,会有什么区别:
我试过这个,似乎也能得到同样的结果num = num ^ (num >> 1); num = num ^ (num >> 2); num = num ^ (num >> 4); num = num ^ (num >> 8); num = num ^ (num >> 16);
- 例如,以位为单位(以8为例)
那么,如果我们应用
x^=x>>1
,会发生什么呢?我们明白了
h g f^h e^g d^f c^e b^d a^c
这看起来像是我们开始时所做的,就好像它是由x^(x>>2)
而不是x^(x>>1)
所做的,所以同样的想法是,只需移动2次即可反转:
h g f e d^h c^g b^f a^e
看起来不错,现在很明显为什么x^=x>>4
会完全恢复正常。对于更多位,相同的模式只会持续一段时间
另一种方法是暂时反转位,将“变灰”变成x⊗ 3带有⊗
在GF(2k)中是乘法,在GF(2k)中奇数乘法是可逆的,3的乘法逆是“所有位集”,您可以发现如下:
- 从y=3和临时反向开始
- 通过将
y
中的第一位(不是lsb)与3异或,将其杀死,并将相应的位设置为相反的值
- 循环直到
y=1
因此,第一步是y=3,i=1
,y=5,i=3
,y=9,i=7
等等,直到您在i
中设置所有位,让我们调用最后的i
inv
然后我们有(x⊗ 3) ⊗ inv=x⊗ (3 ⊗ inv)=x⊗ 1=x
乘以“all bits set”意味着每一位最终都是其自身和所有低位的异或,这是可以使用的
x ^= x << 1
x ^= x << 2
x ^= x << 4
...
课程的最终结果是((x⊗ 3) ⊗ 5) ⊗ 17=x⊗ (3 ⊗ 5.⊗ 17) =x⊗ 127
GF(2k)中的乘法非常好而且是可交换的,所以它可以在任何顺序下很好地完成
其他号码呢
当然可以,只要他们的产品是inv
。但所有其他选择都会导致恼人的/许多被乘数出现。例如,我们可能希望9是一个因子,那么剩下的是199,可以分解为9⊗ 63,依此类推,但这会持续一段时间,直到你有3,5,9,9,17,65,这太可怕了(注意9⊗ 9⊗ 65=1如果有8位,那么就把它踢出去,回到原来的3,5,17)。不过,这是可能的。我尝试了[reverse],似乎也得到了同样的结果。
你能证明这一点吗<代码>与[basic algorithm](右移1…)的[shift by Power of 2]有什么区别?请尝试较小的示例。感谢您的回答,我听说1->2->4->8->16与并行前缀计算有关,并行前缀操作在这里扮演什么角色?@EidolonMK当他们以并行方式计算累积值时,这就是他们所说的,所以这里我们有前缀XOR,并用位级并行计算它有趣的事实:灰色->二进制解码可以用一次无卡利乘法完成,根据-对于\u m128i vx
底部的32位int,\u mm\u clmulepi64\u si128(vx,\u mm\u set\u epi32(0,0,1,-2),0)
在低qword-\u mm\u extract\u epi32(prod,1)
的上半部分生成结果。
h g f e d^h c^g b^f a^e
x ^= x << 1
x ^= x << 2
x ^= x << 4
...
x = x ⊗ 3
x = x ⊗ 5
x = x ⊗ 17
...