求n的下一个符合2的m次方的数

来源:互联网 发布:制作动画片的软件 编辑:程序博客网 时间:2024/05/07 21:40

n不是2的m次方,要求下一个符合2的m次方的数


这个算法很多地方都有了 只是没详解 小的愚昧 整理于此 做个备忘 对你有用更好 没有勿喷

下面是我请教别人的地方,或许他们的解释更容易让你明白

http://topic.csdn.net/u/20110926/09/8ac6fb0f-d59a-4506-8536-c6d1bbb4ea79.html


public static int test(int n){            n -= 1;            n |= n >>> 1;            System.out.println(n);            n |= n >>> 2;            System.out.println(n);            n |= n >>> 4;            System.out.println(n);            n |= n >>> 8;            System.out.println(n);            n |= n >>> 16;            System.out.println(n);            return n + 1;    }

n之所以要减一是为了满足n本身就是2的m次幂这种情况

最高位1扩充到后面的所有位,然后再加一


2的m次幂跟2的m次幂-1的关系是这个算法的关键。比如100 跟111相差一,从另一个角度来看,我可以看成100是111加一求得100的

101的下一个符合2的m次幂的数是100,即四,我们可以这么来做,将最高位1扩充到后面的所有位。


首先将n向右逻辑右移一位(以后说的移位都为逻辑移位),然后再与n求或操作,保存为n,这样保证最高位和右边第一位为1,

接下来都是重复这个动作,但是如何高效的覆盖右边所有位,使之为1呢?


第一次移位然后求或,我们已经获得了最高位和次高位两位为1,那么我们再在第一步的基础上右移两位,然后与第一次得到的最终结果求或,

是不是最高四位都为1了?


现在我们已经获得了最高4位全为1,第三次右移我们可以一次移4位,移完求或后我们可以获得最高8位都为1了。


第四次我们一次移八位,然后求或,可以得到最高16位都为1。


第五次,我们再移16位,现在最高位以下所有的位都为1了,形如11...111的形式


最后,在这个值上加一就求得了n的下一个符合2的m次幂的数



写到这里,我发现完全不用这么麻烦了,首先判断这个数是不是2的m次幂

n & (n-1) == 0

如果等于零则说明他满足条件,返回

不等于零,则将该数左移一位,将最高位以后的所有位清零不就得到了哦







原创粉丝点击