二进制反转整数

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;

}

unsigned char reverse8( unsigned char c )

{

c = ( c & 0x55 ) << 1 | ( c & 0xAA ) >> 1;

c = ( c & 0x33 ) << 2 | ( c & 0xCC ) >> 2;

c = ( c & 0x0F ) << 4 | ( c & 0xF0 ) >> 4;

return c;

}

unsigned long func(unsigned long x)

{

x = (x & 0x55555555UL) + ((x >> 1) & 0x55555555UL);

x = (x & 0x33333333UL) + ((x >> 2) & 0x33333333UL);

x = (x & 0x0f0f0f0fUL) + ((x >> 4) & 0x0f0f0f0fUL);

x = (x & 0x00ff00ffUL) + ((x >> 8) & 0x00ff00ffUL);

x = (x & 0x0000ffffUL) + ((x >> 16) & 0x0000ffffUL);

return x;

}

先看问题1: 反转一个字节。

它的算法是这样的: 首先是2位2位为一组,交换前一半和后一半。再4位4位为一组,交换前一半和后一半。再8位为一组,交换前一半和后一半。

可能还有点说不清楚。我举个例子。

将1 2 3 4 5 6 7 8 反转。

(1)2个2个为一组,交换前一半和后一半, 变成。

2 1 4 3 6 5 8 7

(2)4个4个为一组,交换前一半和后一半,变成

4 3 2 1 8 7 6 5

(3)再8个为一组,交换前一半和后一半, 变成

8 7 6 5 4 3 2 1

反转成功。

这样的算法本来很是简单,很容易用数学归纳法证明其正确。这函数,巧妙就巧妙在作了并行计算,分组,它一次就计算完了。

你可能感兴趣的:(二进制反转整数)