欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

阶乘计算升级版(12位以上的阶乘)

程序员文章站 2022-03-13 13:47:46
...

本题要求实现一个打印非负整数阶乘的函数。

其中N是用户传入的参数,其值不超过1000。如果N是非负整数,则该函数必须在一行中打印出N!的值,否则打印“Invalid input”。

基本思路:
我们知道,当n的值增大时,阶乘的结果会急剧增大,当n大到一定数后即使是unsigned long类型也无法保存结果,这时只能采取别的方法来保存结果.
这里主要采用模拟手算的方法,步骤如下:

  1. 开辟一个足够大的整形数组用于存储计算的结果;
  2. 对于数组的每一位模拟手算的过程:把每一位相乘的结果的个位留下作为本位,高位作为进位加到下一位的计算中去
  3. 对于最高位的进位,同样留下个位作为进位值,进位的高位除以10再将个位作为更高位的值,直到进位位0为止.
  4. 为方便计算将结果逆序存储在数组上

以下为手算的实例以帮助理解

阶乘计算升级版(12位以上的阶乘)

#include <stdio.h>
void fac(const int n);
int main()
{
    int n;
    scanf("%d",&n);
    fac(n);
    return 0;
}
void fac(const int n)
{
    int i,j;
    long result=1;
    if(n>=0&&n<=12)     //可直接计算
    {
        for(i=1;i<=n;i++)
        {
            result*=i;
        }
        printf("%d!=%d\n",n,result);
    }
    else if(n>=12&&n<=1000) //模拟手算过程
    {
        int data[3000];     //存储每一位的结果
        int carry=0;        //存储进位
        int temp;           //存储每一位相乘后的结果
        int digit=1;        //存储当前位数

        data[0] = 1;        //初始化第一位数据

        /*一位一位的相乘,每一位模拟手算的过程*/
        for(i=1;i<=n;i++)
        {
            /*遍历数组的每一位和i相乘*/
            for(j=0;j<digit;j++)
            {
                temp = data[j]*i+carry;
                data[j] = temp%10;      //相乘的结果个位留在本位,高位作为进位加到下一位中去
                carry = temp/10;
            }
            /*最高位有进位的处理:进位可能很大,数组每一位保留进位的个位后进位除以10,依次循环*/
            while(carry!=0) 
            {
                data[digit] = carry%10; //存储进位的个位
                digit++;                //当前位数+1存储进位的下一位
                carry=carry/10;         //进位除以10,为下一次循环做准备
            }
        }

        /*反向输出数组内容*/
        printf("%d!=",n);
        for(i=digit-1;i>=0;i--)
        {
            printf("%d",data[i]);
        }
        printf("\n");
    }
    else
    {
        printf("Invalid input\n");
    }

}

因本人水平有限,难免会有错误的地方,望各路大神多多指教,本人QQ1481263718欢迎来交流