Java 这个程序实际上是如何工作的?

Java 这个程序实际上是如何工作的?,java,binary,bit-manipulation,Java,Binary,Bit Manipulation,我编写了一个递归方法,它将接受一个数字,并返回下一个2的幂。如果输入的数字是二的幂,它将映射到自身。这假定n>0 static int nextPower1(int n) { if(n == 0) { System.out.println("nextPower(" + n + ") = 2"); return 2; } else if(n == 1) { System.out.println("nextPower(" + n + "

我编写了一个递归方法,它将接受一个数字,并返回下一个2的幂。如果输入的数字是二的幂,它将映射到自身。这假定n>0

static int nextPower1(int n) {
    if(n == 0) {
        System.out.println("nextPower(" + n + ") = 2");
        return 2;
    } else if(n == 1) {
        System.out.println("nextPower(" + n + ") = 1");
        return 1;
    } else {
        int lastBit = n & 1;
        int secondLastBit = (n >> 1) & 1;
        int restOfTheBits = (n >> 2);

        int result = nextPower1(restOfTheBits << 1 | secondLastBit ^ lastBit);
        return result << 1;
    }
static int nextPower1(int n){
如果(n==0){
System.out.println(“nextPower(“+n+”)=2”);
返回2;
}else如果(n==1){
System.out.println(“nextPower(“+n+”)=1”);
返回1;
}否则{
int lastBit=n&1;
int secondLastBit=(n>>1)&1;
int restofbits=(n>>2);

int result=nextPower1(restobbits此代码被破坏,它总是返回错误的答案,例如1 后跟一个或多个零,后跟两个1:101110011等。 (因为当它递归时,它将成对的1组合成一个0,从 这一点使得它无法与传入的1000、10000等进行区分。)

(编辑:对于所有具有偶数个1位的值来说都是错误的 msb的右侧。每对xor都为0,丢失必要的信息 为了得到正确的结果。-AR.)

递归循环将最低有效位上卷到数字中 作为卷起部分是否包含任何1的历史记录。 隔离两个最不重要的位只会使代码更难理解; 它正在执行
otherBits=n>>1;返回nextPower1(otherBits^lastBit)

当查看剩下的最后两位时(最重要的位和 汇总历史位),如果历史为零,则为最高有效位 是唯一设置的位,其本身是2的下一次幂。如果历史位 如果是1,那么2的次幂就是下一位的位置,1 超过msb。(如果只有历史记录位工作正常,请参见下文)

代码不会查看最后两位,而是查看 msb和历史记录位。如果为1,则仅设置了msb,历史记录为零,并返回1(self)作为二的幂。如果为0,则历史记录位为 设置,并返回下一个更高的幂(2) 功率(1或2)移回原始msb位置,产生 msb或下一个更大的二次方

但是,由于历史不会通过零传播,因此会中断

要修复,递归需要修复历史(使用OR,而不是XOR),并且 不在末尾将历史记录位混合到msb中,类似于:

nextPower( int n ) {
    if (n == 1) return 1;
    if (n == 2) return 2;
    if (n == 3) return 4;
    return nextPower((n >> 1) | (n & 1)) << 1;
}
nextPower(int n){
如果(n==1)返回1;
如果(n==2)返回2;
如果(n==3)返回4;

return nextPower((n>>1)|(n&1))=0,这是代码明确没有的)

按如下方式修复代码使其工作(请参阅):

import java.util.*;
导入java.lang.*;
导入java.io.*;
/*只有当类是公共的时,类的名称才必须是“Main”*/
表意文字
{
公共静态void main(字符串[]args)引发java.lang.Exception
{
int n;
int结果;
对于(n=0;n1)&1;
int restofbits=(n>>2);

int result=nextPower1(restoff可能是您在不了解xoring如何工作的情况下编写此代码的副本?我在这里有点困惑。“这假定n>0”。那么,为什么要将n=0的结果编码为2?它不应该是2次幂0=1吗?此代码不正确。它返回4作为7的2的下一次幂。它返回8表示13,返回14。返回1表示n=1使代码正确。当n=0返回的值更改为1否时,代码工作;
if(n==0)返回1使3、4、5、6产生2、4、4、4(n==0处理“has lsbits”情况;返回1返回msb,就好像n是2的偶数幂一样)您是正确的。只是通过一个小的修复程序进行了检查并使其工作,尽管不是非常优雅。正如您所说的,您的代码需要进行检查以处理零,该零也将放置在帮助器函数中。是的,工作正常--帮助器计算n的msb,如果n是2的幂,则n==msb(n),否则返回下一个更高的幂(2*msb,==msb(2*n))
nextPower( int n ) {
    if (n == 1) return 1;
    if (n == 2) return 2;
    if (n == 3) return 4;
    return nextPower((n >> 1) | (n & 1)) << 1;
}
import java.util.*;
import java.lang.*;
import java.io.*;

/* Name of the class has to be "Main" only if the class is public. */
class Ideone
{
    public static void main (String[] args) throws java.lang.Exception
    {
        int n;
        int result;
        for (n=0;n<=16;n++) {
            result = nextPower(n);
            System.out.println("Next power of " + n + " is " + result);
        }
    }

    static int nextPower(int n) {
        int result;
        result = nextPower1(n);
        if (n<=1 || result ==n)
            return result;
        else
            return result * 2;
    }


    static int nextPower1(int n) {
        if(n == 0) {
            return 1;
        } else if(n == 1) {
            return 1;
        } else {
            int lastBit = n & 1;
            int secondLastBit = (n >> 1) & 1;
            int restOfTheBits = (n >> 2);

            int result = nextPower1(restOfTheBits << 1 | secondLastBit ^ lastBit);
            return result << 1;
        }
    }
}
Next power of 0 is 1 (0 <= 2 power 0)
Next power of 1 is 1 (1 <= 2 power 0)
Next power of 2 is 2 (2 <= 2 power 1)
Next power of 3 is 4 (3 <= 2 power 2)
Next power of 4 is 4 ...etc
Next power of 5 is 8
Next power of 6 is 8
Next power of 7 is 8
Next power of 8 is 8
Next power of 9 is 16
Next power of 10 is 16
Next power of 11 is 16
Next power of 12 is 16
Next power of 13 is 16
Next power of 14 is 16
Next power of 15 is 16
Next power of 16 is 16