选择哪种数据类型或数据结构来计算100的阶乘?

时间:2013-03-04 15:56:09

标签: java c data-structures

我想过编写一个程序来评估给定整数的阶乘。

按照基础知识,我在java中编写了以下代码:

long fact(int num){
if(num == 1)
 return 1;
else
 return num*fact(num-1);
}

但后来我意识到,对于许多整数输入,结果可能不是所希望的,因此测试直接将输入作为100。

我的怀疑是真的,因为我得到的结果是“0”(原因结果可能超出了长期范围)。

所以,我只是好奇并渴望知道如何让我的程序适用于输入< = 150。

我很感激C编程语言或Java中的任何有效解决方案。

5 个答案:

答案 0 :(得分:12)

BigInteger 是您的班级。它可以存储整数看似任意大小

    static BigInteger fact(BigInteger num) {
        if (num.equals(BigInteger.ONE))
            return BigInteger.ONE;
        else
            return num.multiply(fact(num.subtract(BigInteger.ONE)));
    }

答案 1 :(得分:4)

如果你没有采用天真的因子计算方法,你应该对问题进行一些研究。以下是计算阶乘的一些算法的概述:http://www.luschny.de/math/factorial/conclusions.html

但与其他答案一样,您当前的问题是您需要使用大量实现(例如BigInt)而不是固定大小的整数。

答案 2 :(得分:3)

在C语言中,您可以使用数组来存储大数的阶乘 我的参考:Calculate the factorial of an arbitrarily large number, showing all the digits。这是非常有用的帖子 我在代码中做了一些小改动,转换成C.

int max = 5000;
void factorial(int arr[], int n){//factorial in array
    if (!n) return;
    int carry = 0;
    int i=max-1;
    for (i=max-1; i>=0; --i){
        arr[i] = (arr[i] * n) + carry;
        carry = arr[i]/10;
        arr[i] %= 10;
    }
    factorial(arr,n-1);
}
void display(int arr[]){// to print array
    int ctr = 0;
    int i=0;
    for (i=0; i<max; i++){
        if (!ctr && arr[i])      
            ctr = 1;
        if(ctr)
            printf("%d", arr[i]);
    }
}
int main(){
    int *arr = calloc(max, sizeof(int));
    arr[max-1] = 1;
    int num = 100;
    printf("factorial of  %d is: ",num);
    factorial(arr,num);
    display(arr);
    free(arr);
    return 0;
}

它的工作量为100!见:here Codepad

我想给你两个更有用的帖子的链接 1)How to handle arbitrarily large integers建议GPU MP
2)C++ program to calculate large factorials

答案 3 :(得分:0)

在java中,你有可以存储任意大整数的BigInteger。不幸的是C没有平等。您必须使用第三方库或自己实现大整数。这种方法的典型方法是使用动态分配的数组,在某些数字系统中存储给定数字的每个数字(通常选择超过10的数字,以便减少所需的总位数)。

答案 4 :(得分:0)

十进制(基数为10)的数字大约需要3.3位(确切地说:log(10)/ log(2))。 100!类似于158位数,所以你需要158 * 3.3 = 520位。

C中肯定没有内置类型可以做到这一点。如果您希望析因计算中的每个数字都“存在”,则需要某种形式的特殊库。

使用double会得到一个近似结果(假设double是一个64位浮点值,与IEEE-754兼容,或具有相似的范围 - IEEE-754 {{ 1}}格式将给出大约16个十进制数字(52位精度,除以上面的log(10)/ log(2))。我相信这个值超过16位,所以你不会得到一个确切的值,但它会计算一个10位或更多位数的数字。