将一个字节里的比特头尾翻转
来源:互联网 发布:软件开发公司规章制度 编辑:程序博客网 时间:2024/04/20 17:19
Reverse bits the obvious way
unsigned int v; // input bits to be reversed
unsigned int r = v; // r will be reversed bits of v; first get LSB of v
int s = sizeof(v) * CHAR_BIT - 1; // extra shift needed at end
for (v >>= 1; v; v >>= 1)
{
r <<= 1;
r |= v & 1;
s--;
}
r <<= s; // shift when v's highest bits are zero
On October 15, 2004, Michael Hoisie pointed out a bug in the original version.Randal E. Bryant suggested removing an extra operation on May 3, 2005. Behdad Esfabod suggested a slight change that eliminated one iteration of theloop on May 18, 2005. Then, on February 6, 2007, Liyong Zhou suggested a better version that loops while v is not 0, so rather than iterating over all bits it stops early.
Reverse bits in word by lookup table
static const unsigned char BitReverseTable256[256] =
{
# define R2(n) n, n + 2*64, n + 1*64, n + 3*64
# define R4(n) R2(n), R2(n + 2*16), R2(n + 1*16), R2(n + 3*16)
# define R6(n) R4(n), R4(n + 2*4 ), R4(n + 1*4 ), R4(n + 3*4 )
R6(0), R6(2), R6(1), R6(3)
};
unsigned int v; // reverse 32-bit value, 8 bits at time
unsigned int c; // c will get v reversed
// Option 1:
c = (BitReverseTable256[v & 0xff] << 24) |
(BitReverseTable256[(v >> 8) & 0xff] << 16) |
(BitReverseTable256[(v >> 16) & 0xff] << 8) |
(BitReverseTable256[(v >> 24) & 0xff]);
// Option 2:
unsigned char * p = (unsigned char *) &v;
unsigned char * q = (unsigned char *) &c;
q[3] = BitReverseTable256[p[0]];
q[2] = BitReverseTable256[p[1]];
q[1] = BitReverseTable256[p[2]];
q[0] = BitReverseTable256[p[3]];
The first method takes about 17 operations, and the second takes about 12, assuming your CPU can load and store bytes easily.
On July 14, 2009 Hallvard Furuseth suggested the macro compacted table.
Reverse the bits in a byte with 3 operations (64-bit multiply and modulus division):
unsigned char b; // reverse this (8-bit) byte
b = (b * 0x0202020202ULL & 0x010884422010ULL) % 1023;
The multiply operation creates five separate copies of the 8-bit byte pattern to fan-out into a 64-bit value.The AND operation selects the bits that are in the correct (reversed) positions, relative to each 10-bit groups of bits.The multiply and the AND operations copy the bits from the original byte so they each appear in only one of the 10-bit sets. The reversed positions of the bits from the original byte coincide withtheir relative positions within any 10-bit set.The last step, which involves modulus division by 2^10 - 1, has theeffect of merging together each set of 10 bits (from positions 0-9, 10-19, 20-29, ...) in the 64-bit value. They do not overlap, so the addition steps underlying themodulus division behave like or operations.
This method was attributed to Rich Schroeppel in theProgramming Hacks section of Beeler, M., Gosper, R. W., and Schroeppel, R. HAKMEM. MIT AI Memo 239, Feb. 29, 1972.
Reverse the bits in a byte with 4 operations (64-bit multiply, no division):
unsigned char b; // reverse this byte
b = ((b * 0x80200802ULL) & 0x0884422110ULL) * 0x0101010101ULL >> 32;
The following shows the flow of the bit values with the boolean variables a, b, c, d, e, f, g,
and h
, whichcomprise an 8-bit byte. Notice how the first multiply fans out thebit pattern to multiple copies, while the last multiply combines themin the fifth byte from the right.
abcd efgh (-> hgfe dcba)
* 1000 0000 0010 0000 0000 1000 0000 0010 (0x80200802)
-------------------------------------------------------------------------------------------------
0abc defg h00a bcde fgh0 0abc defg h00a bcde fgh0
& 0000 1000 1000 0100 0100 0010 0010 0001 0001 0000 (0x0884422110)
-------------------------------------------------------------------------------------------------
0000 d000 h000 0c00 0g00 00b0 00f0 000a 000e 0000
* 0000 0001 0000 0001 0000 0001 0000 0001 0000 0001 (0x0101010101)
-------------------------------------------------------------------------------------------------
0000 d000 h000 0c00 0g00 00b0 00f0 000a 000e 0000
0000 d000 h000 0c00 0g00 00b0 00f0 000a 000e 0000
0000 d000 h000 0c00 0g00 00b0 00f0 000a 000e 0000
0000 d000 h000 0c00 0g00 00b0 00f0 000a 000e 0000
0000 d000 h000 0c00 0g00 00b0 00f0 000a 000e 0000
-------------------------------------------------------------------------------------------------
0000 d000 h000 dc00 hg00 dcb0 hgf0 dcba hgfe dcba hgfe 0cba 0gfe 00ba 00fe 000a 000e 0000
>> 32
-------------------------------------------------------------------------------------------------
0000 d000 h000 dc00 hg00 dcb0 hgf0 dcba hgfe dcba
& 1111 1111
-------------------------------------------------------------------------------------------------
hgfe dcba
Note that the last two steps can be combined on some processors because the registers can be accessed as bytes; just multiply so that a register stores the upper 32 bits of the result and the take the low byte. Thus, it may take only 6 operations.
Devised by Sean Anderson, July 13, 2001.
Reverse the bits in a byte with 7 operations (no 64-bit):
b = ((b * 0x0802LU & 0x22110LU) | (b * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16;
Make sure you assign or cast the result to an unsigned char to remove garbage in the higher bits. Devised by Sean Anderson, July 13, 2001. Typo spotted and correction suppliedby Mike Keith, January 3, 2002.
- 将一个字节里的比特头尾翻转
- 怎么把一个字节里的比特顺序倒转?
- 8位字节的比特翻转
- 几种将字符串头尾翻转的方法
- 将一个数的二进制位进行翻转
- 将一个字符串翻转
- matlab 对一个向量实施比特翻转操作的函数bitrevorder()
- 翻转无符号整数的比特位
- 将一个字节的bits逆序
- 将一个链表翻转
- 比特,字节,字符概念的理解
- 比特,字节,字符,字的解释
- 比特,字节,千字节
- 为什么C++里空的类还占一个字节?
- 网络游戏将比特币挖矿程序植入到用户电脑里
- oracle 删除字符串头尾的指定一个字符
- 编写一个程序 将字符串翻转
- 将一个矩阵翻转90度
- IO之字节数组输入输出流
- jquery鼠标拖动特效
- 通用编程能力训练:template
- 24to16
- linux常用svn命令
- 将一个字节里的比特头尾翻转
- 解决局域网共享访问常见问题
- Starting new.
- 查看dll文件被哪些软件调用的命令
- 各大著名汽车标志图 & 来历
- N/A
- 批处理查找和替换文件指定字符串
- 常见算法C#描述
- 测试文章~