gpt4 book ai didi

java - 为什么这两段相似的代码会产生不同的结果呢?

转载 作者:太空狗 更新时间:2023-10-29 21:22:46 25 4
gpt4 key购买 nike

在过去的几个小时里,我一直在尝试使用 Python 作为初学者。我写了一个递归函数,它返回 recurse(x) 作为 x!在 Python 和 Java 中,比较两者。这两段代码是相同的,但出于某种原因,Python 的代码有效,而 Java 的代码无效。在 Python 中,我写道:

x = int(raw_input("Enter: "))

def recurse(num):
if num != 0:
num = num * recurse(num-1)
else:
return 1

return num

print recurse(x)

其中变量num自乘num-1直到为0,并输出结果。在 Java 中,代码非常相似,只是更长:

public class Default {
static Scanner input = new Scanner(System.in);
public static void main(String[] args){

System.out.print("Enter: ");
int x = input.nextInt();
System.out.print(recurse(x));


}

public static int recurse(int num){

if(num != 0){
num = num * recurse(num - 1);
} else {
return 1;
}

return num;

}

如果我输入 25,Python 代码返回 1.5511x10E25,这是正确答案,但 Java 代码返回 2,076,180,480,这不是正确答案,我不确定为什么。

两段代码执行相同的过程:

  • 检查 num 是否为零
  • 如果 num 不为零
    • num = num 乘以 num - 1 的递归
  • 如果 num 为零
    • 返回 1,结束那堆递归调用,并使每个返回的 num 开始相乘
  • 返回数

python中没有括号;我认为这会以某种方式改变一些事情,所以我从 Java 代码中删除了括号,但它并没有改变。将 boolean 值 (num != 0) 更改为 (num > 0) 也没有任何改变。向 else 添加 if 语句提供了更多上下文,但值仍然相同。

在每个点打印 num 的值可以了解函数是如何出错的:

python :

1
2
6
24
120
720
5040
40320
362880
3628800
39916800
479001600
6227020800
87178291200
1307674368000
20922789888000
355687428096000
6402373705728000
121645100408832000
2432902008176640000
51090942171709440000
1124000727777607680000
25852016738884976640000
620448401733239439360000
15511210043330985984000000
15511210043330985984000000

稳步增长。在 Java 中:

 1
2
6
24
120
720
5040
40320
362880
3628800
39916800
479001600
1932053504
1278945280
2004310016
2004189184
-288522240
-898433024
109641728
-2102132736
-1195114496
-522715136
862453760
-775946240
2076180480
2076180480

不是稳定增长。事实上,num 正在返回负数,就好像函数正在返回负数一样,即使 num 不应该小于零。

Python 和 Java 代码执行相同的过程,但它们返回的值截然不同。为什么会这样?

最佳答案

两个字——整数溢出

虽然不是 python 专家,但我认为它可能会根据需要扩展整数类型的大小。

然而,在 Java 中,int 类型的大小是固定的 - 32 位,并且由于 int 是有符号的,我们实际上只有 31 位来表示正数。一旦您分配的数字大于最大值,它就会溢出 int(即 - 没有地方可以表示整数)。

虽然在 C 语言中这种情况下的行为是未定义的,但在 Java 中它是明确定义的,它只占用结果的最少 4 个字节。

例如:

System.out.println(Integer.MAX_VALUE + 1);
// Integer.MAX_VALUE = 0x7fffffff

结果:

-2147483648
// 0x7fffffff + 1 = 0x800000000

编辑

为了更清楚地说明,这里是另一个例子。以下代码:

int a = 0x12345678;
int b = 0x12345678;
System.out.println("a*b as int multiplication (overflown) [DECIMAL]: " + (a*b));
System.out.println("a*b as int multiplication (overflown) [HEX]: 0x" + Integer.toHexString(a*b));
System.out.println("a*b as long multiplication (overflown) [DECIMAL]: " + ((long)a*b));
System.out.println("a*b as long multiplication (overflown) [HEX]: 0x" + Long.toHexString((long)a*b));

输出:

a*b as int multiplication (overflown) [DECIMAL]: 502585408
a*b as int multiplication (overflown) [HEX]: 0x1df4d840
a*b as long multiplication (overflown) [DECIMAL]: 93281312872650816
a*b as long multiplication (overflown) [HEX]: 0x14b66dc1df4d840

并且可以看到第二个输出是第4个输出中最少的4个字节

关于java - 为什么这两段相似的代码会产生不同的结果呢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10527593/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com