Java 第5次迭代后的阶乘循环结果不正确

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--) {

我现在正在学微积分,我想我会做一个快速的程序,给我阶乘10的结果。在测试它时,我注意到在第五次迭代之后我得到了错误的结果。但是,前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
这是一个问题。使用
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);
    }