c - 使用镜像算法进行快速位反转

标签 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;

最佳答案

要理解为什么会这样,首先想一想正常的增量是如何工作的:给定一个任意位模式,增量找到一个连续的运行(可能是空的)直到为零,清除所有的 1,然后设置首先从零到一,像这样:

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 中找到与 Mask 中单独的 1 的位置相匹配的位置零 - 第一个“洞”。循环主体清除目标中的所有 1,从最高阶的开始。循环一停止,Target |= Mask 就会将 1 插入到循环找到的“洞”中。

关于c - 使用镜像算法进行快速位反转,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16980171/

相关文章:

c - ToString() 错误

java - 反转二进制字符串java的位

matlab - 通过 FFT 执行 2D 卷积时的奇怪行为

python - python中的位移位

c++ - 在 C++ 复数的内存布局中

python - scipy.fft.fft 导致的傅里叶系数符号不正确

c - C 中的非 ASCII 字符

c - malloc问题和内存堆

c - "overload"c 中的函数 - 不知道输入参数类型

在 C 中将无符号整数转换为 48 位二进制