您的位置:首页 > 编程语言 > Go语言

阶乘——高精度求法

2013-01-18 10:38 1211 查看
n! = n * (n-1) * (n-2) * ...* 2 * 1

我们经常说一个算法的时间复杂度是指数级或者阶乘级的非常恐怖的。因为一个很小的数阶乘的结果是很大的一个数。12!=479 001 600, 13!就已经超过了int的表示范围。所以当我们要求一个很大的数的阶乘时,必须使用高精度来表示,否则越界。

阶乘的高精度运算可以模拟一个整数与一个大整数的乘法运算,具体运算过程就和做手算乘法一样,无非是每位相乘,超过10进1

注意:上面说的十进一是十进制运算,每一位表示0~9之间的数,为了提高运算速度,我们还可以以100进制,1000进制,10000进制。。。来进行运算。这就有点类似于基数排序的每个桶的表示范围一样。但是如果不是十进制,需要注意一点的就是,假设100进制,我们得到的第i位数是1,当我们输出结果时,如果直接输出1,显然结果不对,我们应该保证每位都占有两位数。

具体代码如下

#include <stdio.h>
#include <string.h>

const int MAXBIT = 40000;

const int BIT = 10000;

int d[MAXBIT];
int f[MAXBIT];

void BigNumberMultiplyWithN(int *digital, int n, int &bitnum)
{
int i;

//digital[bitnum] = 0;
for (i = 0; i < bitnum; i++)
{
digital[i] *= n;
}
for (i = 0; i < bitnum; i++)
{
if (digital[i] >= BIT && i + 1 < bitnum)
{
digital[i+1] += digital[i] / BIT;
digital[i] %= BIT;
}
}
i = bitnum - 1;
while (digital[i] >= BIT)
{
digital[i+1] += digital[i] / BIT;
digital[i++] %= BIT;
bitnum++;
}
}

void Factorial(int n)
{
int bitnum = 1;
memset(d, 0, sizeof(d));
d[0] = 1;
for (int i = 2; i <= n; i++)
{
BigNumberMultiplyWithN(d, i, bitnum);
}

int i;
for (i = bitnum - 1; i >= 0; i--)
if (d[i])
break;
printf("%d", d[i--]);
for (; i >= 0; i--)
printf("%04d", d[i]);
printf("\n");
}

int main(void)
{
int i, j;
int n;
while (scanf("%d", &n) != EOF)
{
Factorial(n);
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Algorithm 高精度