反转一个字节的算法
来源:互联网 发布:weex 设置淘宝镜像 编辑:程序博客网 时间:2024/05/09 00:44
反转函数:
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;
}
...{
c = ( c & 0x55 ) << 1 | ( c & 0xAA ) >> 1;
c = ( c & 0x33 ) << 2 | ( c & 0xCC ) >> 2;
c = ( c & 0x0F ) << 4 | ( c & 0xF0 ) >> 4;
return c;
}
它的算法是这样的:首先是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个为一组,交换前一半和后一半,变成:
8 7 6 5 4 3 2 1
反转成功。
这样的算法本来很是简单,很容易用数学归纳法证明其正确。这函数, 巧妙就巧妙在作了并行计算,分组,它一次就计算完了。
先看第一个语句。c = ( c & 0x55) << 1 | ( c & 0xAA ) >> 1;
0x55其实就是01010101, 0xAA就是10101010
假设 c=abcdefgh
c & 0x55 = 0b0d0f0h, c & 0xAA = a0c0e0g0
跟着,前者左移一位, b0d0f0h0, 后者右移一位, 0a0c0e0g, 再一个|运算,就两位两位交换了位置。
想象一下,你有一个长纸条,分成一格一格,每格写一个字,假如你将纸条每隔一格剪一个小洞,滑一格,覆盖在原来的纸条上,你就会看到两个两个字交换了位置。
(注: |运算可以换成+运算,想一想为什么)
转载自:http://blog.chinaunix.net/u/25096/showart_362366.html
- 反转一个字节的算法
- 反转一个字节 和 判断32位整数二进制中1的个数 的算法
- 反转一个字节 和 判断32位整数二进制中1的个数 的算法(ZZ)
- 反转一个字节 和 判断32位整数二进制中1的个数 的算法
- (转贴)反转一个字节 和 判断32位整数二进制中1的个数 的算法
- 反转一个字节 和 判断32位整数二进制中1的个数 的算法(ZZ)
- 反转一个字节 和 判断32位整数二进制中1的个数 的算法(ZZ)
- 反转一个字节 和 判断32位整数二进制中1的个数 的算法
- 反转一个字节 和 判断32位整数二进制中1的个数 的算法
- 反转一个字节
- 反转一个字节和判断32位整数二进制中1的个数等算法
- 反转一个字符串的算法
- 笔试题--反转一个字节
- 笔试题--反转一个字节
- 算法:反转一个C风格的字符串
- 位运算复习——字节的奇偶校验和反转一个字节中的二进制位
- 算法 - 反转一个单链表
- 反转一个字节(详细解析)
- JSTL与Hibernate的日期问题
- 在Lotus Domino 中应用webservice
- IE vs. FireFox 系列 - showModalDialog
- Ubuntu一些很必要的命令
- Part II RCP 举例
- 反转一个字节的算法
- 告诉你什么是SaaS
- Will Java Die?
- 绿软必备:ActiveXDLL免注册调用的方法(改良自阿国哥的源码)
- .Net开发人员应该下载的十种必备工具(三)
- 学习杂想
- 函数调用约定与函数名称修饰规则
- 在Eclipse中使用JUnit4进行单元测试(中级篇)
- 求32位整数二进制中1的个数