查看: 4688|回复: 6
打印 上一主题 下一主题

二进制高位到低位实现逆变

[复制链接]
跳转到指定楼层
沙发
发表于 2014-8-8 09:22:42 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
1. 编写一个函数,实现将一个32 位int 型数据的二进制高位到低位实现逆变,例如:
1101 0101 变成1010 1011。
这个题目的解决方法很多,代表性的有两种。
  1. int func(unsigned int uiData , int length)
  2. {
  3. unsigned int uiValue = 0 ;
  4. int i = 0 ;
  5. for ( i = 0 ; i < length ; i++ )
  6. {
  7. uiValue = (uiValue << 1) + (uiData & 0x01) ;
  8. uiData = uiData >> 1 ;
  9. } return uiValue ;
  10. }
复制代码

这个方法比较常见,通过移位的方法将高位到低位实现逆序。但是这个方法存在唯一的
不足之处是效率低,要进行32 次移位和运算。


回复

使用道具 举报

板凳
 楼主| 发表于 2014-8-8 09:24:13 | 只看该作者
  1. int func (unsigned int uiData)
  2. {
  3. unsigned int uiValue = 0 ;
  4. /* 分而治之的思想*/
  5. /* 高16 位和低16 互换*/
  6. uiValue = ((uiData >> 16)&0x0000ffff) |
  7. ((uiData << 16)&0xffff0000);
  8. /*高低16 位中的高低8 位互换*/
  9. uiValue = ((uiValue >> 8)&0x00ff00ff) |
  10. ((uiValue << 8)&0xff00ff00);
  11. /*8 位中的高低4 位互换*/
  12. uiValue = ((uiValue >> 4)&0x0f0f0f0f) |
  13. ((uiValue << 4)&0xf0f0f0f0);
  14. /*4 位中的高低2 位互换*/
  15. uiValue = ((uiValue >> 2)&0x33333333) |
  16. ((uiValue << 2)&0xcccccccc);
  17. /*2 位中的高低位互换*/
  18. uiValue = ((uiValue >> 1)&0x55555555) |
  19. ((uiValue << 1)&0xaaaaaaaa);
  20. return uiValue ;
复制代码
这个程序只需要位操作5 次,就能实现高位到低位的逆序。我们逐句程序分析一下。
假设uiData = 1100 0101 0101 1100 1100 0101 0101 1111。执行完成下面这句
程序,
/* 高16 位和低16 互换*/
uiValue = ((uiData >> 16)&0x0000ffff) | ((uiData << 16)&0xffff0000);
得到1100 0101 0101 1111 1100 0101 0101 1100,也就是高16 位和低16
位互换。

回复 支持 反对

使用道具 举报

地板
 楼主| 发表于 2014-8-8 09:26:15 | 只看该作者
执行完成:
/*高低16 位中的高低8 位互换*/
uiValue = ((uiValue >> 8)&0x00ff00ff) | ((uiValue << 8)&0xff00ff00);
得到0101 1111 1100 0101 0101 1100 1100 0101,也就是高低16 位中高8
位和低8 位互换。

执行完成:
/*8 位中的高低4 位互换*/
uiValue = ((uiValue >> 4)&0x0f0f0f0f) | ((uiValue << 4)&0xf0f0f0f0);
得到1111 0101 0101 1100 1100 0101 0101 1100,也就是从高位起,每8 位
段的高4 位和低4 位完成互换。

执行完成:
/*4 位中的高低2 位互换*/
uiValue = ((uiValue >> 2)&0x33333333) | ((uiValue << 2)&0xcccccccc);
得到1111 0101 0101 0011 0011 0101 0101 0011,也就是从高位起,每4 位
段的高2 位和低2 位完成互换。

执行完成:
/*2 位中的高低位互换*/
uiValue = ((uiValue >> 1)&0x55555555) | ((uiValue << 1)&0xaaaaaaaa);
得到1111 1010 1010 0011 0011 1010 1010 0011。也就是从高位起,每2 位
段的高1 位和低1 位完成互换。和原始数据1100 0101 0101 1100 1100 0101 0101
1111 进行对比,逆序。

回复 支持 反对

使用道具 举报

4#
发表于 2014-8-8 09:52:53 | 只看该作者
受教了,我长知识了
回复 支持 反对

使用道具 举报

5#
发表于 2014-8-8 10:01:32 | 只看该作者
领教了,看似简单但是含义丰富
回复 支持 反对

使用道具 举报

6#
发表于 2014-8-8 12:30:03 | 只看该作者
{:soso_e179:}顶你
回复 支持 反对

使用道具 举报

7#
发表于 2014-8-10 14:34:22 | 只看该作者
高手都是在考虑优化
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 加入因仑

本版积分规则

快速回复 返回顶部 返回列表