将一个数的二进制位进行翻转

    在学习redis源码的时候,看到了这段代码。很少写blog,不太会表达自己的观点。

static unsigned long rev(unsigned long v) 
{   
    unsigned long s = 8 * sizeof(v); // bit size; must be power of 2
    unsigned long mask = ~0;
    while ((s >>= 1) > 0) 
   {
        mask ^= (mask << s);      
        v = ((v >> s) & mask) | ((v << s) & ~mask);
   }
   return v;
}
    举一个例:所有的数都用二进制表示

    假设v=11001010,unsigned long为1个字节(方便)

    s = 4      mask = 00001111      v = (00001100 & 00001111) | (10100000 & 11110000) = 10101100

    s = 2      mask = 00110011      v = (00101011 & 00110011) | (10110000 & 11001100) = 10100011

    s = 1      mask = 01010101      v = (01010001 & 01010101) | (01000110 & 10101010) = 01010011

    如果有一个数为value,占1个字节(0-7),第k位,翻转后位于第7-k位。


    在这个特定的例子中 位于s处,翻转后位于e处,且x1 + x2 == 7,对于一个8位的数进行翻转相当于每一位都要移动7次,7 = 4 + 2 + 1,从while( (s >>=1) > 0)可以看出。

所以当s=4,相当于移动了4位,s=2时,移动了2位,s=1时,移动了1位,这里使用了位运算的技巧。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值