首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >为什么在这个Java函数中,2的31次方返回一个负数?

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

Stack Overflow用户
提问于 2018-10-07 02:14:27
回答 2查看 1.6K关注 0票数 1

分配:

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

public static int recPow(int n)

函数必须考虑所有情况,并进行详尽的测试。

My Problem

我不明白为什么当我输入recPow(31)时,代码返回-2147483648而不是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);
        }
    }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-10-07 02:48:28

这是由于int数据类型溢出造成的。

Java的int大小是32位,因此范围是-2,147,483,648到2,147,483,647。

2^31 = 2147483648

因此,当2,147,483,647的二进制值为011111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111

如果您尝试超出此限制(2,147,483,647) 1(即,将其加1),则会将符号位更改为1,从而使此int为负。

因此,它将变成1000000000000000000000000000000000000000 (1 + 31个0),给出答案-2147483648。

票数 4
EN

Stack Overflow用户

发布于 2018-10-07 02:19:59

较大的指数返回0(然而,我认为这可能与我们需要使用整数和长整型有关)。

对,是这样。

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,它的限制要大得多。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52682013

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档