按位反转无符号字符

 题目:

一个unsigned char,记为src,把其中的字节高位和低位全部互换

 

分析:

想找出src中某一位的bit,肯定是要拿一个该位为1其他位为0的char,记为flag,和他进行&,取出该位的值,记为onebit。把该onbit左移(或者右移,看是否现在已经到了中间点)一定位数,就变到了他应该放到的位。

然后flag左移一位,再次&,取出下一位。这样,依次取出来然后把所有取出来的onebit进行 | 相连, 就得到了换位之后的结果。

 

算法代码:

  1. unsigned char ReverseBits(unsigned char src)
  2. {
  3.     unsigned char flags = 0x1;
  4.     unsigned char onebit = 0x0;
  5.     unsigned char result = 0x0;
  6.     int size = sizeof(unsigned char) * 8;
  7.     int left = size - 1;    // (onebit << left) as one bit in result
  8.     for ( int i = 0; i < size; i++ )
  9.     {
  10.         onebit = src & flags;
  11.         if ( left > 0 )
  12.             onebit = onebit << left;
  13.         else if ( left < 0 )
  14.             onebit = onebit >> -left;
  15.         left -= 2;
  16.         result |= onebit;
  17.         flags = flags << 1;
  18.     }
  19.     return result;
  20. }

测试代码:

  1. int main(int argc, char* argv[])
  2. {
  3.     unsigned char src = 0xaa;
  4.     unsigned char expected = 0x55;
  5.     unsigned char result = ReverseBits(src);
  6.     if ( result == expected )
  7.         printf("OK: %x", result);
  8.     else
  9.         printf("Error: %x", result);
  10.     getchar();
  11.     return 0;
  12. }

[20081209 补记]

发现上面的实现可行,但是有一些无用的步骤,所以参考其他人的代码,做了如下的修改:

  1. // good ones
  2. unsigned int Reverse( unsigned int n ) 
  3.     unsigned int result = 0; 
  4.     int length = 32;
  5.     for ( int i = 0; i < length; i++ ) 
  6.     { 
  7.         result = result << 1; 
  8.         result = result | ( n & 0x1 ); 
  9.         n = n >> 1; 
  10.     } 
  11.     return result; 

同样,是《编程之美》上面,有很多关于数字里面有多少位二进制1的问题。解法:

1,如上述,按位右移<<;

2,做减法,进行&&,如果>0,则计数+1.其理论基础是:最低一个1(第i位)减1之后,该位为0,该位之后所有的为1;也就是说,从第i位到第0位的所有二进制都进行的反转,所以对这部分&&必为0

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值