我目前正在学习预微积分,我想我应该做一个快速的程序,给出阶乘10的结果。当我测试它的时候,我注意到我在第5次迭代后得到了不正确的结果。然而,前4次迭代是正确的。
public class Factorial
{
public static void main(String[] args)
{
int x = 1;
int factorial;
for(int n = 10; n!=1; n--)
{
factorial = n*(n-1);
x = x * factorial;
System.out.printf("%d ", x);
}
}//end of class main
}//end of class factorial

发布于 2012-12-08 07:25:49
这是一个Integer Overflow问题。使用long或unsigned long而不是int。(正如@Dunes建议的那样,在处理非常大的数字时,您最好的选择是BigInteger,因为理论上它永远不会溢出)
基本思想是带符号的整数在-2,147,483,648 to 2,147,483,647之间存储数字,它们以二进制位的形式存储(计算机中的所有信息都以1和0的形式存储)
正数用0存储在最高有效位,负数用1存储在最高有效位。如果你的正数在二进制表示中变得太大,数字会转移到有符号的位,并将你的正数变成负数的二进制表示。
然后,当阶乘的大小甚至超过了unsigned int所能存储的值时,它将“绕回”,并丢失从其最重要的(有符号)位开始的结转--这就是为什么您会在输出中看到有时正负交替的模式。
发布于 2012-12-08 07:27:28
您的阶乘公式不正确。您将拥有以下内容:
但是错误的结果是因为您达到了其他人所指出的int类型的最大值
你的代码应该是
public class Factorial
{
public static void main(String[] args)
{
double factorial = 1;
for(int n = factorial; n>=1; n--)
{
factorial = factorial * n;
System.out.printf("%d ", factorial );
}
}
}发布于 2012-12-08 07:31:37
除了其他答案提到的溢出之外,您的阶乘算法也是不正确的。10!如果要计算10*9*8*7*6*5*4*3*2*1,您正在计算(10*9)*(9*8)*(8*7)*(7*6)*...
尝试将您的循环更改为以下内容:
int x = 1;
for(int n = 10; n > 1 ; n--)
{
x = x * n;
System.out.printf("%d ", x);
}如果您试图计算更高数字的阶乘,最终会溢出,但是int足够大,可以计算10的阶乘。
https://stackoverflow.com/questions/13772608
复制相似问题