使用镜像算术进行快速位反转

时间:2013-06-07 09:01:23

标签: c bit-manipulation fft

我在Sergey Chernenko的一篇关于FFT的文章中包含了一个C函数。该功能通过执行奇偶分解来重新排列数据。但是不是使用位反转,而是通过以镜像方式添加1来实现,这比我测试的其他反转代码快得多。

  /*
      http://www.librow.com/articles/article-10 (Sergey Chernenko)
   */
  void rearrange(float* Data, const unsigned int N) {

     //   Swap position
     unsigned int Target = 0;
     //   Process all positions of input signal
     for (unsigned int Position = 0; Position < N; ++Position)
     {
        //   Only for not yet swapped entries
        if (Target > Position)
        {
           //   Swap entries
           const float Temp = Data[Target];
           Data[Target] = Data[Position];
           Data[Position] = Temp;
        }
        //   Bit mask
        unsigned int Mask = N;
        //   While bit is set
        while (Target & (Mask >>= 1))
           //   Drop bit
           Target &= ~Mask;
        //   The current bit is 0 - set it
        Target |= Mask;
     }
  }

我感兴趣的部分是镜像递增代码。我理解C中的逐位操作,我可以在心理上仔细阅读这个片段并验证它是否有效。我还不明白为什么它有效。我如何提出这个解决方案?

        //   Bit mask
        unsigned int Mask = N;
        //   While bit is set
        while (Target & (Mask >>= 1))
           //   Drop bit
           Target &= ~Mask;
        //   The current bit is 0 - set it
        Target |= Mask;

2 个答案:

答案 0 :(得分:2)

要理解为什么这有效,首先要考虑正常增量如何起作用:给定一个任意位模式,一个增量找到一个连续的运行(可能是空的)直到零,清除所有的一个,并设置第一个零到一个,像这样:

0000 0001 -  0 ->  1 | No ones at the back (an empty run): insert 1 right away.
0111 1000 -  7 ->  8 | Replace a run of three ones with zeros, then insert 1
1011 1100 - 11 -> 12 | Replace a run of two ones with zeros, then insert 1

现在考虑一下你的算法:常规增量检测从数字后面开始的运行;你的循环检测从数字前面开始的运行。由于您说算法“以镜像方式添加一个”,N必须是Target中可能存在的两个最高幂的两倍。 while循环尝试在Target中找到1中孤独Mask的位置与零匹配的位置 - 第一个“洞”。循环体清除目标中的所有部分,从最高阶开始。一旦循环停止,Target |= Mask1插入到循环找到的“洞”中。

答案 1 :(得分:1)

它只是按位置模拟加法1。除非职位逆转。

要添加1,您将继续修改位位置(从最低位开始),直到不再有进位。

相关问题