首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >阶乘循环结果在第5次迭代后不正确

阶乘循环结果在第5次迭代后不正确
EN

Stack Overflow用户
提问于 2012-12-08 07:23:35
回答 3查看 945关注 0票数 4

我目前正在学习预微积分,我想我应该做一个快速的程序,给出阶乘10的结果。当我测试它的时候,我注意到我在第5次迭代后得到了不正确的结果。然而,前4次迭代是正确的。

代码语言:javascript
复制
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

EN

回答 3

Stack Overflow用户

发布于 2012-12-08 07:25:49

这是一个Integer Overflow问题。使用longunsigned long而不是int。(正如@Dunes建议的那样,在处理非常大的数字时,您最好的选择是BigInteger,因为理论上它永远不会溢出)

基本思想是带符号的整数在-2,147,483,648 to 2,147,483,647之间存储数字,它们以二进制位的形式存储(计算机中的所有信息都以10的形式存储)

正数用0存储在最高有效位,负数用1存储在最高有效位。如果你的正数在二进制表示中变得太大,数字会转移到有符号的位,并将你的正数变成负数的二进制表示。

然后,当阶乘的大小甚至超过了unsigned int所能存储的值时,它将“绕回”,并丢失从其最重要的(有符号)位开始的结转--这就是为什么您会在输出中看到有时正负交替的模式。

票数 9
EN

Stack Overflow用户

发布于 2012-12-08 07:27:28

您的阶乘公式不正确。您将拥有以下内容:

  1. 第一步: n*(n-1) = 10 *9= 90 => x= 1*90 =90
  2. 第二步: n*(n-1) =9*8= 72 => x= 90*72 = 6480或者,应该是: 10 *9*8 => 720

但是错误的结果是因为您达到了其他人所指出的int类型的最大值

你的代码应该是

代码语言:javascript
复制
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 );

        }
    }
}
票数 3
EN

Stack Overflow用户

发布于 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)*...

尝试将您的循环更改为以下内容:

代码语言:javascript
复制
int x = 1;
for(int n = 10; n > 1 ; n--)
{
    x = x * n;
    System.out.printf("%d ", x);
}

如果您试图计算更高数字的阶乘,最终会溢出,但是int足够大,可以计算10的阶乘。

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

https://stackoverflow.com/questions/13772608

复制
相关文章

相似问题

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