Algorithm 格雷码算法(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 =

我最近遇到了格雷码,我一直在努力研究将格雷码转换回二进制(32位或更少)的高效算法

这就是我说的代码。下面是我的问题:

  • 此代码与正常代码(右移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
      ...