天马座 发表于 2021-6-11 15:48:23

经典的二进制翻转

这是jdk中的一段代码,感觉很不错,转过来,给出了c实现   /**
   * Returns the value obtained by reversing the order of the bits in the
   * two's complement binary representation of the specified {@code int}
   * value.
   *
   * @param i the value to be reversed
   * @return the value obtained by reversing order of the bits in the
   *   specified {@code int} value.
   * @since 1.5
   */
    public static int reverse(int i) {
      // HD, Figure 7-1
      i = (i & 0x55555555) << 1 | (i >>> 1) & 0x55555555;
      i = (i & 0x33333333) << 2 | (i >>> 2) & 0x33333333;
      i = (i & 0x0f0f0f0f) << 4 | (i >>> 4) & 0x0f0f0f0f;
      i = (i << 24) | ((i & 0xff00) << 8) |
            ((i >>> 8) & 0xff00) | (i >>> 24);
      return i;
    }
下面是c语言版本
int reverse(int i) {
      
      i = (i & 0x55555555) << 1 | (i >> 1 & 0x7fffffff) & 0x55555555;
      i = (i & 0x33333333) << 2 | (i >> 2 & 0x3fffffff) & 0x33333333;
      i = (i & 0x0f0f0f0f) << 4 | (i >> 4 & 0xfffffff) & 0x0f0f0f0f;
      i = (i << 24) | ((i & 0xff00) << 8) |
            ((i >> 8 & 0xffffff) & 0xff00) | (i >> 24 & 0xff);
      return i;
    }

0xAA55 发表于 2021-6-12 17:49:33

请使用 uint32_t ,因为你直接使用 int 的话,不同编译器的 << >> 和 & 优先级不同,会导致你的代码在不同编译器上行为不同。

tlwh163 发表于 2023-10-15 09:34:35

本帖最后由 tlwh163 于 2023-10-16 06:19 编辑

'    'x = (x Shr 1) And &H55555555 Or (x Shl 1) And &HAAAAAAAA    ''奇偶位交换
'    'x = (x Shr 2) And &H33333333 Or (x Shl 2) And &HCCCCCCCC    ''2Bit为1单元,奇偶单元交换
'    'x = (x Shr 4) And &H0F0F0F0F Or (x Shl 4) And &HF0F0F0F0    ''4Bit为1单元,奇偶单元交换
'    'x = (x Shr 8) And &H00FF00FF Or (x Shl 8) And &HFF00FF00    ''8Bit为1单元,奇偶单元交换
'    'x = (x Shr 16) And &H0000FFFF Or (x Shl 16) And &HFFFF0000''16Bit为1单元,奇偶单元交换

不知道这个和楼主的代码 原理是不是一样? 哪个更有效率?
使用VFB对2种方法进行编译,GCC2级优化,汇编代码殊途同归...

'    Asm
'      mov   edx,       ''8B5424 04
'      mov   eax, edx            ''89D0
'      Add   edx, edx            ''01D2
'      Shr   eax, 1            ''D1E8
'      And   edx, &HAAAAAAAA   ''81E2 AAAAAAAA
'      And   eax, &H55555555   ''25 55555555
'      Or    eax, edx            ''09D0
'      mov   edx, eax            ''89C2
'      Shr   edx, 2            ''C1EA 02
'      Shl   eax, 2            ''C1E0 02
'      And   edx, &H33333333   ''81E2 33333333
'      And   eax, &HCCCCCCCC   ''25 CCCCCCCC
'      Or    edx, eax            ''09C2
'      mov   eax, edx            ''89D0
'      Shr   eax, 4            ''C1E8 04
'      Shl   edx, 4            ''C1E2 04
'      And   eax, &H0F0F0F0F   ''25 0F0F0F0F
'      And   edx, &HF0F0F0F0   ''81E2 F0F0F0F0
'      Or    edx, eax            ''09C2
'      mov   eax, edx            ''89D0
'      bswap eax               ''0FC8
'      ret   4                   ''C2 0400
'    End Asm

Kagamia 发表于 2023-12-27 18:17:07

这个经典的算法也被收录在bithacks列表中:https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel

上面也摘录了一些更modern的算法,比如查表法和64位运算法,不知道现代编译器是否会识别原始算法的pattern并且编译成更快的方式。
页: [1]
查看完整版本: 经典的二进制翻转