在java中计算大于整数和长整数的阶乘?

在java中计算大于整数和长整数的阶乘?,java,biginteger,factorial,Java,Biginteger,Factorial,我在这里和谷歌搜索了几天,还问了我的编程朋友。 不幸的是,我仍然不明白如何更改我的代码 我的程序计算给定数字的阶乘。然后它提供一个数字,表示阶乘答案包含的位数。然后将这些数字的值相加,得到一个总数 我的程序适用于1之间的任何数字!和31!。。。如果你把任何超过31!(例如50!或100!)它不起作用,只返回负数,没有总数 我希望你们能给我指出正确的方向或者给我一些建议。 我理解使用大整数可能是一个解决方案,但我个人不理解它们,因此来到这里 任何帮助都将不胜感激。谢谢 package ja

我在这里和谷歌搜索了几天,还问了我的编程朋友。 不幸的是,我仍然不明白如何更改我的代码

我的程序计算给定数字的阶乘。然后它提供一个数字,表示阶乘答案包含的位数。然后将这些数字的值相加,得到一个总数

我的程序适用于1之间的任何数字!和31!。。。如果你把任何超过31!(例如50!或100!)它不起作用,只返回负数,没有总数

我希望你们能给我指出正确的方向或者给我一些建议。 我理解使用大整数可能是一个解决方案,但我个人不理解它们,因此来到这里

任何帮助都将不胜感激。谢谢

    package java20;

    /**
    * Program to calculate the factorial of a given number.
    * Once implemented, it will calculate how many digits the answer includes.
    * It will then sum these digits together to provide a total.
     * @author shardy
     * date: 30/09/2012
     */

    //import java.math.BigInteger;
    public class Java20 {

    /**
    * @param args the command line arguments
    */
    public static void main(String[] args) {

    //Using given number stored in factorialNo, calculates factorial
    //currently only works for numbers between 1! and 31! :(
        int fact= 1;
        int factorialNo = 10;

        for (int i = 1; i <= factorialNo; i++)
            {
               fact=fact*i;
            }

        System.out.println("The factorial of " + factorialNo + 
                " (or " + factorialNo + "!) is: " + fact);

        //Using answer stored in fact, calculates how many digits the answer has
        final int answerNo = fact;
        final int digits = 1 + (int)Math.floor(Math.log10(answerNo));

        System.out.println("The number of digits in the factorials "
                + "answer is: " + digits);        

        //Using remainders, calculates each digits value and sums them together
        int number = fact;
        int reminder;
        int sum = 0;

        while(number>=1)
            {
             reminder=number%10; 
             sum=sum+reminder;
             number=number/10;
            }

        System.out.println("The total sum of all the " + digits 
                + " idividual digits from the answer of the factorial of " 
                + factorialNo + " is: " + sum);

      }
    }
包java20;
/**
*计算给定数的阶乘的程序。
*一旦实现,它将计算答案包含多少位数。
*然后,它将这些数字相加,得出总数。
*@author shardy
*日期:30/09/2012
*/
//导入java.math.biginger;
公共类Java20{
/**
*@param指定命令行参数
*/
公共静态void main(字符串[]args){
//使用存储在factorialNo中的给定数字,计算factorial
//当前仅适用于1!和31!之间的数字:(
int-fact=1;
int factorialNo=10;
对于(int i=1;i=1)
{
提醒=编号%10;
总和=总和+提醒;
数字=数字/10;
}
System.out.println(“所有“+位的总和
+“从的阶乘的答案中提取的单个数字”
+factorialNo+是:“+和”;
}
}

您可以在java中使用BigInteger,它可以包含任意数量的数字

    BigInteger fact= BigInteger.ONE;
    int factorialNo = 10;

    for (int i = 2; i <= factorialNo; i++){
      fact = fact.multiply(new BigInteger(String.valueOf(i)));
    }

    System.out.println("The factorial of " + factorialNo +
                                " (or " + factorialNo + "!) is: " + fact);
   final int digits = fact.toString().length();

   BigInteger number = new BigInteger(fact.toString());
   BigInteger reminder;
   BigInteger sum = BigInteger.ZERO;
   BigInteger ten = new BigInteger(String.valueOf(10));

   while(number.compareTo(BigInteger.ONE)>=0)
     {
     reminder=number.mod(ten);
     sum=sum.add(reminder);
     number=number.divide(ten);
     }

     System.out.println("The total sum of all the " + digits
                     + " idividual digits from the answer of the factorial of "
                     + factorialNo + " is: " + sum
biginger事实=biginger.ONE;
int factorialNo=10;
对于(int i=2;i=0)
{
提醒=number.mod(十);
sum=sum.add(提醒);
数字=数字。除以(十);
}
System.out.println(“所有“+位的总和
+“从的阶乘的答案中提取的单个数字”
+factorialNo+是:“+sum”

编辑:代码经过改进,与作者的代码兼容

如果要计算(m!/n!),最好使用阶乘的对数

你也应该考虑这两个改进:

  • 记住,不要重新计算。一旦你计算了这些来之不易的值,就把它们存储起来
  • 您应该使用来计算阶乘。您使用循环的方式是向学生展示的最简单的方式。中有一个很好的
    ln(gamma(x))
    in的实现
  • 如果你必须,你可以使用BigDigPiple,但这是最后一招。你仍然应该考虑这些要点。< /P> 有一个gamma函数实现可以从中获得。源代码可能不像naive方法那样熟悉,但是如果您看到它是如何实现的,那么很明显,即使对于中等参数,它也更有效

    如果你把任何超过31的东西放进去(例如50!或100!),它就不会 工作,只返回负数,没有总数

    这是因为原始整数类型在超过其最大可能值时会受到影响。计算阶乘有这样的趋势

    我希望你们能给我指出正确的方向 一些建议。我知道使用大整数可能是一个解决方案,但是我 我个人不了解他们,所以来这里

    使用
    biginger
    是一种可能的解决方案,这是正确的。例如,您可以执行以下操作:

    public BigInteger factorial(int num) {
        if (num < 0) {
            throw new IllegalArgumentException("Not today!");
        }
    
        BigInteger result = BigInteger.ONE;
    
        for (int next = 2; next <= num; next++) {
            result = result.multiply(new BigInteger(Integer.toString(next, 10)));
        }
    
        return result;
    }
    
    public biginger阶乘(int num){
    if(num<0){
    抛出新的IllegalArgumentException(“不是今天!”);
    }
    BigInteger结果=BigInteger.ONE;
    
    对于(int next=2;next,这可能是一个有用的链接)您的消息“Not today”没有提供信息,因此最好使用“Factorial未定义负数[“+num+”]”之类的内容@Tim-同意。示例代码的要点是指出应该以某种方式处理负值/无效值,而不是推荐一种具体的方法。可能有人会争辩说,返回
    null
    是处理该问题的一种同样有效的方法,或者应该使用其他一些异常类型。重要的一点是检查无效数字。检查内部发生的情况多少取决于个人偏好和/或项目/组织编码准则。使用循环计算阶乘是最简单的方法。另一种方法是使用递归,但由于堆栈大小的限制。两者都很简单,但效率低且幼稚。Gamma funct函数调用是一个函数调用。没有循环,没有递归,没有堆栈帧。我没有计算操作数,但2的操作数和100000的操作数是一样的。它远远小于循环或递归,只有在输入值较大的情况下,它的优势才会增加。如果我将循环到一个函数中,它仍然是O(N),但“这是一个函数调用”。非常感谢,这非常好并且工作得非常好。不幸的是,它与math.log10或while循环不兼容:(请不要忘记将其标记为答案,以便其他人在遇到相同问题时可以看到。当然:)我只是想先解决math.log10问题…它看起来几乎完全不兼容..只是确认一下,“final int digits=fact.toString().length();”告诉您阶乘答案中有多少位数?似乎比Math.Log10方法简单得多?它只告诉您字符串有多少个字符=位数。这是我在Java中经常使用的方法。