lowbit 与 highbit

lowbit

lowbit 在竞赛中还是很常见的,比如树状数组就必须要用 lowbit

lowbit 的原理是利用原码, 反码, 补码的性质来获得数字在二进制下最低位的 1。理解了原码,反码,补码,就不难理解 lowbit 了。

lowbit 代码如下:

inline int lowbit(int x) {  
    return x & -x;  
}

以一个例子来理解上面的代码(假设你已经理解了原码,反码,补码):

  • 我们假设 n=88 的二进制为 : 00001000
  • 8 取反的二进制为:11110111
  • 再对取反 8 加一(补码)的二进制为:11111000
  • 进行与操作之后:00001000
    就得到了我们的 lowbit(8)=8

highbit

这个相对来说要少见些。

顾名思义,它干的事与 lowbit 相反,求的是数字在二进制下最高位的 1

其原理是将一个数二进制下最高位的 1 及其右面的每一位都补充为 1,然后把最高位右面的都减掉,剩下就是最高位的 1。代码如下:

int highbit(int x){  
    x |= x >> 1;  
    x |= x >> 2;  
    x |= x >> 4;  
    x |= x >> 8;  
    x |= x >> 16;  
    return x - (x >> 1);  
}

为什么这样写呢?

我们假设 x 在二进制下只有最高位是 1,其余位都是 0。通过 highbit 函数的第一行,我们通过右移 1 位并与原来的 x 异或,将 x 最高位往右一位填充为了 1,现在总共有连续的两个 1。接着通过第二行,可以继续向右填充两位,现在统共有 41 了。接下来的代码以此类推,我们就可以把右面全部填充为 1 了,最后 x - (x >> 1) 就可以得到我们想要的 highbit 了。

推广一下,如果最高位右面还有 1,上面的代码依旧是正确的。

上面的函数返回值是 int 型的,如果用别的类型,可以自行调整右移位数。

posted @   jxyanglinus  阅读(93)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示