猿问

为什么在这个 Java 函数中 2 的 31 次方返回负数?

任务:


编写一个递归函数 recPow,用 Java 计算 n >= 0 时的 2n。该函数将具有以下配置文件:


public static int recPow(int n)

该功能必须考虑所有情况并进行详尽的测试。


我的问题


我不明白为什么当我输入时我的代码返回 -2147483648recPow(31)而不是 2147483648。我知道你们中的一些人可能会告诉我切换到 long 而不是 int,但我相信由于分配的措辞,我需要坚持使用 int。我从来都不是很擅长计算数字,如果有人能帮助我理解为什么会发生这种情况,我会非常感激。


此外 - 更大的指数返回 0(但是我认为这可能与我们需要使用整数与长整数的事实有关。)


我的代码


public static int baseNum = 2, powResult = 1;


public static int recPow(int n) {

    //if the int is not bigger than 0 

    //must only accept ints

    if (n < 0) {

        throw new IllegalArgumentException("n has to be > 0");

    } else {

        //recursion here

        //base number = 2

        if (n==0) {

            return powResult;

        } else {

            powResult = powResult * baseNum;

            return recPow(n - 1);

        }

    }

}


青春有我
浏览 345回答 2
2回答

白衣非少年

这是由于int数据类型溢出。Java 的int大小是 32 位,因此范围是 -2,147,483,648 到 2,147,483,647。2^31 = 2147483648因此它溢出到 -2147483648,因为 2,147,483,647 的二进制值是 01111111111111111111111111111111(一个 0 和 31 个 1),其中第一位是“符号位”(2 的补码形式)。如果您尝试将这个限制 (2,147,483,647) 超出 1(即加 1),它会将符号位更改为 1,使其为int负。所以它会变成 1000000000000000000000000000000(1 个一和 31 个零),给你答案 -2147483648。

繁花不似锦

较大的指数返回 0(但是我认为这可能与我们需要使用 int 与 long 的事实有关。)正确的。int i = (int) 2147483648L; // -2147483648 due to over flowint j = i * 2; // 0 due to overflow.您可以使用long但是这有同样的问题,但价值更高。public static long recPower(int baseNum, int power) {&nbsp; &nbsp; if (power < 0) throw new IllegalArgumentException();&nbsp; &nbsp; return power == 0 ? 1L : baseNum * recPower(baseNum, power - 1);}检查溢出的一种方法是查看public static long recPower(int baseNum, int power) {&nbsp; &nbsp; if (power < 0) throw new IllegalArgumentException();&nbsp; &nbsp; return power == 0 ? 1L : baseNum * recPower(baseNum, power - 1);}或检查溢出public static long recPower(int baseNum, int power) {&nbsp; &nbsp; if (power < 0) throw new IllegalArgumentException();&nbsp; &nbsp; return power == 0 ? 1L&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: Math.multiplyExact(baseNum, recPower(baseNum, power - 1));}您可以使用 BigInteger,它的限制要大得多。
随时随地看视频慕课网APP

相关分类

Java
我要回答