求大于等于(小于等于)一个整数最小2次幂算法

给一个整数,如何求得大于等于该整数的最小2次幂呢?
最近看ConcurrentHashMap的源码中有这么一段代码,这段代码就是解决这个问题的最好答案。现在我给大家来讲解一下这段代码的意思吧。

/**
     * Returns a power of two table size for the given desired capacity.
     * See Hackers Delight, sec 3.2
     */
    private static final int tableSizeFor(int c) {
        int n = c - 1;
        n |= n >>> 1;
        n |= n >>> 2;
        n |= n >>> 4;
        n |= n >>> 8;
        n |= n >>> 16;
        return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
    }

为什么先-1呢?原因很简单,如果一个数不是2的乘方,那么它本身减1之后,最高位的位置是不会变的,而我们后续会把最高位后的所有低位都变成1,所以这些低位本身是1或者是0都是不重要的。而如果输入数本身就是2的乘方,那么我们减1之后,最高位的位置会往右移动一位(剩余都是1),我们把它+1之后,又变成了它“原来的模样”,符合我们的要求。

首先一个整数肯定是32位那我就随机取一个数字,我用*表示我不知道这一位是1还是0都好这样更能说明问题。
0000 001x xxxx xxxx,右移1位,
0000 0001 xxxx xxxx,然后将两个数字进行或操作可得到
0000 0011 xxxx xxxx,右移2位;
0000 0000 11xx xxxx,再将这两个数字进行或操作;
0000 0011 11xx xxxx,右移4位;
0000 0000 0011 11xx,再将这两个数字进行或操作;
0000 0011 1111 11xx,右移8位;
0000 0000 0000 0011,再将这两个数字进行或操作;
0000 0011 1111 1111,在对这个数字进行+1;
0000 0100 0000 0000,得到最终答案。
从这个例子中我们很明显可以看出通过移位+或操作算出了最终的结果。
首先在计算机中位运算是最快的计算方式,所以这种算法固然是最快的;其次整个移位过程一直到右移16位结束,这是因为如果一个int型是32位,出去1位的符号位,剩下的有效表述数字大小的有31位,当执行右移16位结束后就可以完全保证每一位都被运算过。

如果这道题让求的是小于等于该整数的最小2次幂的话,只需要将刚才最终的计算结果右移1位就好。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值