用int来表示整数的阶乘到12!就是极限了,再大就要超出整数的范围了
那么更大的数的阶乘怎么办, long long int是64位,但是也只能容纳20!的阶乘,更大的数必须另想办法
直接上代码, 10000! 0.1s左右可得(i7的cpu哈)。
这个时间也不包含输出部分, 具体的时间和硬件有关系
基本原理就是用数组模拟寄存器乘法计算的原理
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#define MAX 50000
// 10000! 用到数组不到4000位,如果要计算更大的, 需要把MAX放大
// facth和factd两个函数返回的数值就是表示数组实际使用的大小
// 如果想放开这个限制,可以用vector动态数组模板来替代facts这个静态数组
int facts[MAX];
int facth(int n) { // 16进制的乘法
if ( 0==n || 1==n ) {
facts[0] = 1;
return 1;
}
memset(facts, 0, MAX*sizeof(int));
facts[0] = 1; int len = 1;
for (int i=2; i<n; i++) {
int extend = 0;
long long int d;
for ( int j=0; j<len; j++) {
long long int a = facts[j];
d = a * i + extend;
facts[j] = d & 0xFFFFFFFF;
extend = d >> 32;
}
if ( extend>0) {
facts[len] = extend;
len ++; extend = 0;
}
// printf("%2d: %8x - %8x - %8x - %8x \n", i, facts[3], facts[2], facts[1], facts[0]);
}
return len;
}
int factd(int n) { // 16进制的乘法
if ( 0==n || 1==n ) {
facts[0] = 1;
return 1;
}
memset(facts, 0, MAX*sizeof(int));
facts[0] = 1; int len = 1;
for (int i=2; i<=n; i++) {
int extend = 0;
long long int d;
for ( int j=0; j<len; j++) {
long long int a = facts[j];
d = a * i + extend;
if ( d > 1000000000) {
facts[j] = d % 1000000000;
extend = d / 1000000000;
} else
facts[j] = d, extend=0;
}
if ( extend>0) {
facts[len] = extend;
len ++;
extend = 0;
}
//printf("%2d: %9d - %9d - %9d - %9d \n", i, facts[3], facts[2], facts[1], facts[0]);
}
return len;
}
void printd(int len) {
printf("len:%d\n", len);
if (len>1) {
printf("%d ", facts[len-1]);
for ( int i=len-2; i>=0; i--)
printf("%09d ", facts[i]);
} else
printf("%d", facts[0]);
}
void printh(int len) {
printf("len:%d\n", len);
if (len>1) {
printf("%X ", facts[len-1]);
for ( int i=len-2; i>=0; i--)
printf("%08X ", facts[i]);
} else
printf("%X", facts[0]);
}
#include <time.h>
int main() {
clock_t start,end;
int len = 0;
start = clock();
len = facth(10000); // 十六进制的表达
// len = factd(10000); // 十进制的表达
end = clock();
printh(len); // 输出16进制,和facth配合使用
// printd(len); // 输出十进制,和factd配合使用
double endtime=(end-start)*1.0/CLOCKS_PER_SEC;
printf("\n\ntime:%lf(s)\n", endtime);
return 0;
}

本文介绍了一种使用数组模拟寄存器乘法计算大数阶乘的方法,通过自定义函数facth和factd实现了10000!的快速计算,并提供了C语言实现代码。
1621

被折叠的 条评论
为什么被折叠?



