曲径通幽论坛

 找回密码
 立即注册
搜索
查看: 4303|回复: 0
打印 上一主题 下一主题

大数的阶乘

[复制链接]

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34397
跳转到指定楼层
楼主
发表于 2011-9-1 11:59:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
由于类型的限制,大数的阶乘会导致变量溢出,所以无法直接得到结果,比如求 100 的阶乘即使是 64 位的 long long 类型也不行。

如果使用 python 语言,那么得到 100 的阶乘最为容易:
[Plain Text] 纯文本查看 复制代码
#!/usr/bin/python

import math

print math.factorial(100)

运行输出:
$ python temp.py
93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000

对于 C 语言,这么大的数考虑用数组来存放。为了计算方便,可以考虑倒序存放阶乘结果,如 8! (40320)可以如下存放:
02304


当笔算一个乘法时,我们会先从个位乘起,然后依次往上。每位相乘的结果分为有两部分,一部分是商( C 语言里的 / 除法运算结果,这个结果将作为进位,在下一次运算中加到其余数中),一部分是余数,余数部分会和上一次运算的进位相加后保存下来。


下面程序就是模拟笔算的过程:
[C++] 纯文本查看 复制代码
#include <stdio.h>


#define FC 100        /*100的阶乘*/


static int a[FC * 3];    /*数组用来存储结果*/


int main()
{
    int i, j;
    int len = 1;    /*每次运算时对结果长度的跟踪*/
    int temp, carry;    /*temp为每位相乘时的结果;carry为每位相乘时的进位*/


    a[1] = 1;


    for (i = 2; i <= FC; i++) {    /*总阶乘长度循环*/
        carry = 0;
        
        for (j = 1; j <= len; j++) {    /*每次阶乘结果处理*/
            temp = a[j]*i + carry;    /*每位算得的结果加上上次运算的进位*/
            a[j] = temp % 10;    
            carry = temp / 10;    /*求进位*/
            if (j == len && carry !=0)    /*最高位算得的结果如果有进位则本次阶乘结果的长度则增加1位*/
                len++;
        }
    }
    for (i = len; i >=1; i--)
        printf ("%d", a[i]);


    printf ("\n");    
    return 0;
}

运算结果和 python 脚本里的相同。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|曲径通幽 ( 琼ICP备11001422号-1|公安备案:46900502000207 )

GMT+8, 2025-6-17 13:27 , Processed in 0.087096 second(s), 23 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表