为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

青春有我 2021-11-03 10:56:02
任务:编写一个递归函数 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);        }    }}
查看完整描述

2 回答

?
白衣非少年

TA贡献1155条经验 获得超0个赞

这是由于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。


查看完整回答
反对 回复 2021-11-03
?
繁花不似锦

TA贡献1851条经验 获得超4个赞

较大的指数返回 0(但是我认为这可能与我们需要使用 int 与 long 的事实有关。)


正确的。


int i = (int) 2147483648L; // -2147483648 due to over flow

int j = i * 2; // 0 due to overflow.

您可以使用long但是这有同样的问题,但价值更高。


public static long recPower(int baseNum, int power) {

    if (power < 0) throw new IllegalArgumentException();

    return power == 0 ? 1L : baseNum * recPower(baseNum, power - 1);

}

检查溢出的一种方法是查看


public static long recPower(int baseNum, int power) {

    if (power < 0) throw new IllegalArgumentException();

    return power == 0 ? 1L : baseNum * recPower(baseNum, power - 1);

}

或检查溢出


public static long recPower(int baseNum, int power) {

    if (power < 0) throw new IllegalArgumentException();

    return power == 0 ? 1L 

           : Math.multiplyExact(baseNum, recPower(baseNum, power - 1));

}

您可以使用 BigInteger,它的限制要大得多。


查看完整回答
反对 回复 2021-11-03
  • 2 回答
  • 0 关注
  • 344 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信