Java 第5次迭代后的阶乘循环结果不正确
我现在正在学微积分,我想我会做一个快速的程序,给我阶乘10的结果。在测试它时,我注意到在第五次迭代之后我得到了错误的结果。但是,前4次迭代是正确的Java 第5次迭代后的阶乘循环结果不正确,java,Java,我现在正在学微积分,我想我会做一个快速的程序,给我阶乘10的结果。在测试它时,我注意到在第五次迭代之后我得到了错误的结果。但是,前4次迭代是正确的 public class Factorial { public static void main(String[] args) { int x = 1; int factorial; for(int n = 10; n!=1; n--) {
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
这是一个问题。使用long
或unsigned long
代替int
。(正如@Dunes所建议的,在处理非常大的数字时,您的最佳选择实际上是biginger
,因为理论上它永远不会溢出)
其基本思想是,有符号整数存储-2147483648到2147483647
之间的数字,这些数字存储为二进制位(计算机中的所有信息存储为1
和0
)
正数与0
一起存储在最高有效位,负数与1
一起存储在最高有效位。如果您的正数在二进制表示法中变得太大,数字将转到有符号位,并将正数转换为负数的二进制表示法
然后,当阶乘变得比
无符号int
所能存储的还要大时,它将“环绕”并失去其最重要(有符号)的结转位-这就是为什么您在输出中有时会看到正负值交替的模式。您超过了int
类型(2147483647)的容量,因此您的结果会回到最小int
值。尝试改用long
话虽如此,您当前使用的方法不会得到正确的答案:实际上,您当前正在计算10!^2
为什么要把事情复杂化?您可以轻松地执行以下操作:
long x = 1L;
for(int n = 1; n < 10; n++)
{
x *= n;
System.out.println(x);
}
长x=1L;
对于(int n=1;n<10;n++)
{
x*=n;
系统输出println(x);
}
1.
2.
6.
24
120
720
5040
40320
362880
显示连续的阶乘直到10代码>已到达
另外,正如其他人所提到的,如果您需要的值大于long
所能支持的值,则应使用该值,该值支持任意精度。您的阶乘公式不正确。您将拥有的是:
步骤1:n*(n-1)=10*9=90=>x=1*90=90
第二步:n*(n-1)=9*8=72=>x=90*72=6480,或者应该是:10*9*8=>720
但是错误的结果来自这样一个事实,即您达到了其他人指出的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 );
}
}
}
除了其他答案提到的溢出之外,您的阶乘算法也不正确。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的阶乘。long将在20左右溢出代码>和双精度在200之前的某个地方有溢出代码>和在此之前很久的精度损失。如果您试图避免溢出,那么biginger
可能是更好的选择。
int x = 1;
for(int n = 10; n > 1 ; n--)
{
x = x * n;
System.out.printf("%d ", x);
}