怎么用C写阶乘?

时间:2022-09-02 09:35:53

I need to input this equation and there's a factorial in it. I would like to know if there was something like * = multiplication or pow(1,3) for factorial of something in C.

我需要输入这个方程,里面有一个阶乘。我想知道C中的某个数的阶乘是* =乘法还是p (1,3)

term = pow(-1, K) * pow(x, 2K)/(2K)

The factorial would be for the last 2K.

阶乘是最后2K的阶乘。

7 个解决方案

#1


5  

Factorials are easy to calculate, after all n! is just the product of all numbers up to n. But there is a practical problem: Factorials overflow pretty quickly. A 32-bit int can hold 12!, a 64-bit int 20!.

阶乘很容易计算,毕竟n!是所有数的乘积,直到n,但有一个实际的问题:阶乘溢出很快。32位int可以容纳12!,一个64位的int 20!

Depending on how your series converges, you might overflow the valid range.

根据您的级数收敛的方式,您可能会溢出有效范围。

With approximation series like yours, it is usually better to find a means to represent term k by means of term k − 1. In your case:

像你这样的近似系列,它通常是更好的找到一个意味着代表k−1 k的词汇。在你的例子:

    term = pow(-1, k) * pow(x, 2*k) / fact(2*k)

you can represent a term as

你可以把一项表示为

    term[k + 1] = -term[k] * pow(x, 2) / ((2*k - 1) * (2*k - 2))

and your series becomes:

和你的系列就变成:

    double f(double x)
    {
        double term = 1.0;
        double res = term;
        int k = 0;

        while (k < 100) {
            double old = res;

            term = -term * (x / (2*k + 1)) * (x / (2*k + 2));
            res += term;

            if (res == old) break;
            k++;
        }

        return res;
    }

This function will use at most 100 iterations to calculate the cosine. It stops when the term doesn't contribute to the result. In practice, it reaches the result with about 10 iterations, so in that case the regular factorial calculations would have been accurate enough. Still, calculating them over and over is wasteful.

这个函数将使用最多100次迭代来计算余弦值。当这个术语不影响结果时,它就停止了。在实践中,它在大约10次迭代后得到结果,因此在这种情况下,常规的阶乘计算应该足够准确。然而,一遍又一遍地计算是浪费。

#2


5  

Rarely you need a function for computing factorials. Factorials grow so fast that a look-up-table is sufficient for the few values for which the computation does not overflow. If you are computing terms in a loop, you can avoid computing the factorial using an accumulator for the entire term.

很少需要一个函数来计算阶乘。阶乘增长得如此之快,以致于查找表对于计算不会溢出的少数值来说已经足够了。如果在循环中计算项,可以避免使用累加器计算整个周期的阶乘。

K = 0;
term = 1;

while (K<N) {

   /* use term */
   do_something_with(term);

   /* update term for new value of K */
   K += 1;
   term = -term * x*x / (2*K*(2*K-1));
}

If that seems unclear to you, you can first derive this program where the accumulators are explicit, and then combine the update step into a single variable like above. This program will still have problems with the factorial computation blowing up.

如果您不清楚这一点,您可以首先推出这个程序,在这个程序中,累加器是显式的,然后将更新步骤合并到上面的单个变量中。这个程序仍然会有阶乘计算失败的问题。

K = 0;
pow_minus_1_K = 1;
pow_x_2K = 1;
factorial_2K = 1;

while (K<N) {

   /* compute term */
   term = pow_minus_1_K * pow_x_2K/factorial_2K;

   /* update accumulators for new value of K */
   K += 1;
   pow_minus_1_K = -pow_minus_1_K;
   pow_x_2K *= x*x;
   factorial_2K *= 2*K*(2*K-1);
}

#3


3  

If for some reason recursive functions leave you scratching your head, you can also implement it without recursion:

如果由于某些原因,递归函数让您摸不着头脑,您也可以不使用递归实现它:

/* calculate n factorial */
unsigned long long nfact (int n)
{
    if (n <= 1) return 1;

    unsigned long long s = n;

    while (--n)
        s *= n;

    return s;
}

(note: it is up to you to you to implement a test for overflow, if desired)

(注意:如果需要,您可以对溢出进行测试)

#4


2  

There is no predefined function for factorial, but it can be recursively implemented as follows.

没有预定义的阶乘函数,但是可以递归地实现如下。

int factorial( int a )
{
    if ( 0 == a )
        return 1;
    else
        return a * factorial( a - 1 );
}

People who like the ? operator might implement the function as follows.

喜欢的人?操作符可以实现如下函数。

int factorial( int a )
{
    return 0 == a ? 1 : ( a * factorial( a - 1 ) );
}

If a non-recursive formulation is desired, the implementation can be done as follows.

如果需要使用非递归公式,可以按照以下方式实现。

int factorial( int a )
{
    int Result = 1;
    for ( int i = a; i > 0; Result *= i, i-- );
    return Result;
}

#5


2  

I think using recursion for this problem is a good way to get started with recursion and understand the way it works, but it's not efficient enough since you're calling a function every time. If you want to know why, do a test and see how long it takes. Although I should say, the iterative method is not significantly better either.

我认为使用递归来解决这个问题是一种很好的方法,可以开始使用递归并理解它的工作方式,但是由于每次都调用一个函数,它的效率还不够高。如果你想知道为什么,做个测试,看看需要多长时间。尽管我应该说,迭代方法也不是很好。

From Code Complete by Steve McConnell:

Steve McConnell完整的代码:

Don't use recursion for factorials or Fibonacci numbers

不要对阶乘或斐波那契数列使用递归

One problem with computer-science textbooks is that they present silly examples of recursion. The typical examples are computing a factorial or computing a Fibonacci sequence. Recursion is a powerful tool, and it's really dumb to use it in either of those cases. If a programmer who worked for me used recursion to compute a factorial, I'd hire someone else.

计算机科学教科书的一个问题是它们给出了递归的愚蠢例子。典型的例子是计算阶乘或计算斐波那契数列。递归是一个强大的工具,在这两种情况中使用递归都是很愚蠢的。如果一个为我工作的程序员用递归法计算阶乘,我会雇别人。

So when keep that in mind when going over the recursive versions that are posted here. Now, how to write one.

因此,当我们考虑递归的版本时,请记住这一点。现在,如何写一个。

Basically you have a base case for when the number is less than 1, and a general recursive case. You generally have a base case and a recursive case in a recursive function. For a factorial, it would look something like this:

基本上,当数小于1时,你有一个基本情况,还有一个一般的递归情况。通常在递归函数中有一个基本情况和一个递归情况。对于阶乘,它看起来是这样的:

int factorial_rec(int number)
{
    if (number == 0)
    {
        return 1;
    }else
    {
        return number * factorial_rec(number - 1);
    }
}

#6


0  

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

Include the above code and call this method to get factorial of a number.

包括上面的代码,并调用此方法来获得数字的阶乘。

#7


0  

The code to find factorial of a given number using recursive algorithm can be as shown below :

使用递归算法求给定数的阶乘的代码如下所示:

#include<stdio.h>
int fact(int n)
{
    if(!n)
        return 1;
    else
        return (n*fact(n-1));
}
void main()
{
    int n;
    printf("Enter number : ");
    scanf("%d",&n);
    printf("\nFactorial of %d is : %d",n,fact(n));
}

#1


5  

Factorials are easy to calculate, after all n! is just the product of all numbers up to n. But there is a practical problem: Factorials overflow pretty quickly. A 32-bit int can hold 12!, a 64-bit int 20!.

阶乘很容易计算,毕竟n!是所有数的乘积,直到n,但有一个实际的问题:阶乘溢出很快。32位int可以容纳12!,一个64位的int 20!

Depending on how your series converges, you might overflow the valid range.

根据您的级数收敛的方式,您可能会溢出有效范围。

With approximation series like yours, it is usually better to find a means to represent term k by means of term k − 1. In your case:

像你这样的近似系列,它通常是更好的找到一个意味着代表k−1 k的词汇。在你的例子:

    term = pow(-1, k) * pow(x, 2*k) / fact(2*k)

you can represent a term as

你可以把一项表示为

    term[k + 1] = -term[k] * pow(x, 2) / ((2*k - 1) * (2*k - 2))

and your series becomes:

和你的系列就变成:

    double f(double x)
    {
        double term = 1.0;
        double res = term;
        int k = 0;

        while (k < 100) {
            double old = res;

            term = -term * (x / (2*k + 1)) * (x / (2*k + 2));
            res += term;

            if (res == old) break;
            k++;
        }

        return res;
    }

This function will use at most 100 iterations to calculate the cosine. It stops when the term doesn't contribute to the result. In practice, it reaches the result with about 10 iterations, so in that case the regular factorial calculations would have been accurate enough. Still, calculating them over and over is wasteful.

这个函数将使用最多100次迭代来计算余弦值。当这个术语不影响结果时,它就停止了。在实践中,它在大约10次迭代后得到结果,因此在这种情况下,常规的阶乘计算应该足够准确。然而,一遍又一遍地计算是浪费。

#2


5  

Rarely you need a function for computing factorials. Factorials grow so fast that a look-up-table is sufficient for the few values for which the computation does not overflow. If you are computing terms in a loop, you can avoid computing the factorial using an accumulator for the entire term.

很少需要一个函数来计算阶乘。阶乘增长得如此之快,以致于查找表对于计算不会溢出的少数值来说已经足够了。如果在循环中计算项,可以避免使用累加器计算整个周期的阶乘。

K = 0;
term = 1;

while (K<N) {

   /* use term */
   do_something_with(term);

   /* update term for new value of K */
   K += 1;
   term = -term * x*x / (2*K*(2*K-1));
}

If that seems unclear to you, you can first derive this program where the accumulators are explicit, and then combine the update step into a single variable like above. This program will still have problems with the factorial computation blowing up.

如果您不清楚这一点,您可以首先推出这个程序,在这个程序中,累加器是显式的,然后将更新步骤合并到上面的单个变量中。这个程序仍然会有阶乘计算失败的问题。

K = 0;
pow_minus_1_K = 1;
pow_x_2K = 1;
factorial_2K = 1;

while (K<N) {

   /* compute term */
   term = pow_minus_1_K * pow_x_2K/factorial_2K;

   /* update accumulators for new value of K */
   K += 1;
   pow_minus_1_K = -pow_minus_1_K;
   pow_x_2K *= x*x;
   factorial_2K *= 2*K*(2*K-1);
}

#3


3  

If for some reason recursive functions leave you scratching your head, you can also implement it without recursion:

如果由于某些原因,递归函数让您摸不着头脑,您也可以不使用递归实现它:

/* calculate n factorial */
unsigned long long nfact (int n)
{
    if (n <= 1) return 1;

    unsigned long long s = n;

    while (--n)
        s *= n;

    return s;
}

(note: it is up to you to you to implement a test for overflow, if desired)

(注意:如果需要,您可以对溢出进行测试)

#4


2  

There is no predefined function for factorial, but it can be recursively implemented as follows.

没有预定义的阶乘函数,但是可以递归地实现如下。

int factorial( int a )
{
    if ( 0 == a )
        return 1;
    else
        return a * factorial( a - 1 );
}

People who like the ? operator might implement the function as follows.

喜欢的人?操作符可以实现如下函数。

int factorial( int a )
{
    return 0 == a ? 1 : ( a * factorial( a - 1 ) );
}

If a non-recursive formulation is desired, the implementation can be done as follows.

如果需要使用非递归公式,可以按照以下方式实现。

int factorial( int a )
{
    int Result = 1;
    for ( int i = a; i > 0; Result *= i, i-- );
    return Result;
}

#5


2  

I think using recursion for this problem is a good way to get started with recursion and understand the way it works, but it's not efficient enough since you're calling a function every time. If you want to know why, do a test and see how long it takes. Although I should say, the iterative method is not significantly better either.

我认为使用递归来解决这个问题是一种很好的方法,可以开始使用递归并理解它的工作方式,但是由于每次都调用一个函数,它的效率还不够高。如果你想知道为什么,做个测试,看看需要多长时间。尽管我应该说,迭代方法也不是很好。

From Code Complete by Steve McConnell:

Steve McConnell完整的代码:

Don't use recursion for factorials or Fibonacci numbers

不要对阶乘或斐波那契数列使用递归

One problem with computer-science textbooks is that they present silly examples of recursion. The typical examples are computing a factorial or computing a Fibonacci sequence. Recursion is a powerful tool, and it's really dumb to use it in either of those cases. If a programmer who worked for me used recursion to compute a factorial, I'd hire someone else.

计算机科学教科书的一个问题是它们给出了递归的愚蠢例子。典型的例子是计算阶乘或计算斐波那契数列。递归是一个强大的工具,在这两种情况中使用递归都是很愚蠢的。如果一个为我工作的程序员用递归法计算阶乘,我会雇别人。

So when keep that in mind when going over the recursive versions that are posted here. Now, how to write one.

因此,当我们考虑递归的版本时,请记住这一点。现在,如何写一个。

Basically you have a base case for when the number is less than 1, and a general recursive case. You generally have a base case and a recursive case in a recursive function. For a factorial, it would look something like this:

基本上,当数小于1时,你有一个基本情况,还有一个一般的递归情况。通常在递归函数中有一个基本情况和一个递归情况。对于阶乘,它看起来是这样的:

int factorial_rec(int number)
{
    if (number == 0)
    {
        return 1;
    }else
    {
        return number * factorial_rec(number - 1);
    }
}

#6


0  

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

Include the above code and call this method to get factorial of a number.

包括上面的代码,并调用此方法来获得数字的阶乘。

#7


0  

The code to find factorial of a given number using recursive algorithm can be as shown below :

使用递归算法求给定数的阶乘的代码如下所示:

#include<stdio.h>
int fact(int n)
{
    if(!n)
        return 1;
    else
        return (n*fact(n-1));
}
void main()
{
    int n;
    printf("Enter number : ");
    scanf("%d",&n);
    printf("\nFactorial of %d is : %d",n,fact(n));
}