最小的计算大数阶乘的c程序

liangbch 2012-04-26 07:03:59
加精
我刚写了一个计算大数阶乘的c语言小程序,可计算20000以内任意一个整数的阶乘,只有123个字节,见下。不知有人能否打破这一纪录。
int a[N*5]={1},n=N,i,c,m=1;main(){for(;n;n--){for(c=i=0;i<m||c;)a[i++]=(c+=a[i]*n)%10,c/=10;m=i;}for(;m;)putch(a[--m]+48);}


编译和运行方法:
下面在windows+VC2008 和linux中编译这个程序的例子,定义N的值为99,源文件是fac_v9.c,

a) .在Windows + VC2008 环境下编译

1.进入VS2008命令行窗口,我这里通过开始菜单“Microsoft Visual C++ 2008 Express Edition -》Visual Studio Tools -》Visual Studio 2008 Command Prompt” 进入

2.输入命令:cl /c /D "N=99" fac_v9.c

3.输入命令: link /subsystem:console fac_v9.obj /out:fac.exe
4.输入命令fac.exe,便可输出99的阶乘

b) 在Linux下编译。

1. 在终端窗口输入 gcc -DN=99 fac_v9.c -o fac

2. 输入命令./fac,可以输出99的阶乘

...全文
6119 91 打赏 收藏 转发到动态 举报
写回复
用AI写文章
91 条回复
切换为时间正序
请发表友善的回复…
发表回复
fancy3304594 2012-05-03
  • 打赏
  • 举报
回复
写程序需要毅力和兴趣
MichealTX 2012-05-03
  • 打赏
  • 举报
回复
楼主,表用斯特林公式,你见过哪个正常初中生就学斯特林公式了?这个我觉得就是大数乘法先打表,然后根据输入去查表。必须AC![Quote=引用 97 楼 的回复:]

引用 93 楼 的回复:
关于阶乘的有难度一道题目
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2277


算法很简单,c语言知识+不超过初中数学内容 便可解答。倒是输入输出花了我不少时间,起初用scanf,无法检测出空的输入(直接输入回车换行),遂改用gets,终于得到解决。
以下是我的代码。

……
[/Quote]
liangbch 2012-05-03
  • 打赏
  • 举报
回复
如果你真想弄懂他的话,请看我的博客,4行代码计算9999的阶乘,本文采用由易到难的顺序,将一个最普通的、易懂的程序改写成为一个非常简洁的版本,不过代码的可读性差了好多。
如果你依然看不懂该文的代码,请
大数阶乘之计算从入门到精通中的入门篇。
ioaq 2012-05-03
  • 打赏
  • 举报
回复
[Quote=引用楼主 的回复:]
我刚写了一个计算大数阶乘的c语言小程序,可计算20000以内任意一个整数的阶乘,只有123个字节,见下。不知有人能否打破这一纪录。
C/C++ code
int a[N*5]={1},n=N,i,c,m=1;main(){for(;n;n--){for(c=i=0;i<m||c;)a[i++]=(c+=a[i]*n)%10,c/=10;m=i;}for(;m;)putch(a[--m]+48)……
[/Quote]

请问这是什么算法啊?
能解释解释么?
  • 打赏
  • 举报
回复
[Quote=引用 43 楼 的回复:]
听说过64K 3D动画吗?
[/Quote]
见过
liangbch 2012-05-03
  • 打赏
  • 举报
回复
int get_first_dig(int N)
{
double f1=(double)N * log10((double)N);
double f2= f1 - (int)floor(f1);
return (int)(pow(10.0,f2));
}


首先,我的这段代码,已经通过了,请看http://acm.zju.edu.cn/onlinejudge/showRuns.do?contestId=1&problemCode=2277&judgeReplyIds=5。

本来,ACM比赛重在独立计算,公布解法是大忌,因为一旦公布答案,好多人就可以搜索到这段代码而轻易通过这道题,这样对其他人不公平。我冒着被别人唾骂的风险给出了全部代码,非但没有收到感谢的话,反被指责,真是五味杂陈啊!!!

本来以为,93楼既然参加ACM比赛,应该有一定的数学功底,所以没有对代码做太多解释。看来我我高估了93楼了。现在解释一下这个函数是怎么工作的。



1. 根据常用对数的性质,若x的常用对数表示为 n + f (n为整数部分,f为小数部分), 则x=10^(n +f)= 10^n * 10^f, 因为0<=f<1,故1<=10^f<10
如 250的常用对数为 2.39794,这里 n=2,f=0.39794, 则250=10^2 * 10^0.39794 = 100*2.5, 故250的科学计数法写法为2.50e2,数x的科学计数法的数值部分(这里是2.5)的整数部分(这里是2)就是这个数最左边的数字。

2. 我们知道,对数可以化乘除法为加减法,化乘方/开方为乘除法,这里仅说说乘方运算。

令x=N^N,两边取对数得,
log10(x)= log10(N^N)=N*log10(N),令y=log10(x), y的小数部分为f,则x的最左边的数字为10^f的整数部分。

函数get_first_dig的第1行“double f1=(double)N * log10((double)N);”求出N^N的常用对数f1
函数get_first_dig的第2行“double f2= f1 - (int)floor(f1);” 求出N^N的常用对数的小数部分f2
函数get_first_dig的第3行“return (int)(pow(10.0,f2))” 10^f2的整数部分,就是N^N的最左边的数字


这道题目做不出来的同学,说明你初中数学的对数部分没有学好,我之前所说的 “c语言知识+不超过初中数学内容”并没有夸大其辞。
ioaq 2012-05-03
  • 打赏
  • 举报
回复
好厉害
流星陨落 2012-05-03
  • 打赏
  • 举报
回复
[Quote=引用 100 楼 的回复:]

羡慕,刚学的菜鸟,表示亚历山大!
[/Quote]
++
liangbch 2012-05-03
  • 打赏
  • 举报
回复
[Quote=引用 102 楼 的回复:]
楼主,表用斯特林公式,你见过哪个正常初中生就学斯特林公式了?这个我觉得就是大数乘法先打表,然后根据输入去查表。必须AC!

算法很简单,c语言知识+不超过初中数学内容……
[/Quote]
这道题根本就不是计算阶乘,而是计算 N的N次方的10进制形式的最高位数,我什么时候用斯特林公式了,先把题目读懂再说。
foilsman 2012-05-03
  • 打赏
  • 举报
回复
用递归比较简洁:
(defun jsen(n) (if (= n 0) 1 (* n (jsen (1- n)))))
doudoutu12345 2012-05-03
  • 打赏
  • 举报
回复
我也觉得确实是厉害
yuan_chuan 2012-05-02
  • 打赏
  • 举报
回复
无意义。 有兴趣去参加 国际C语言混乱代码大赛
http://sd.csdn.net/a/20120425/2805007.html
KID_coder 2012-05-02
  • 打赏
  • 举报
回复
奇葩。
semandseo 2012-05-02
  • 打赏
  • 举报
回复
羡慕,刚学的菜鸟,表示亚历山大!
hantongjing001 2012-05-02
  • 打赏
  • 举报
回复
内容简单,程序需要的就是通俗易懂。简洁。不过这个太简洁了。
one_millon 2012-05-02
  • 打赏
  • 举报
回复
楼主的程序能否解释一下呢
liangbch 2012-05-02
  • 打赏
  • 举报
回复
[Quote=引用 93 楼 的回复:]
关于阶乘的有难度一道题目
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2277
[/Quote]

算法很简单,c语言知识+不超过初中数学内容 便可解答。倒是输入输出花了我不少时间,起初用scanf,无法检测出空的输入(直接输入回车换行),遂改用gets,终于得到解决。
以下是我的代码。

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int get_first_dig(int N)
{
double f1=(double)N * log10((double)N);
double f2= f1 - (int)floor(f1);
return (int)(pow(10.0,f2));
}

int main()
{
int i,first_dig;
char buff[256];

while(1)
{
memset(buff,0,sizeof(buff));
gets(buff);
if ( buff[0]==0)
break;
sscanf(buff,"%d",&i);
first_dig=get_first_dig(i);
printf("%d\n",first_dig);
}
return 0;
}


faxianLZD 2012-05-01
  • 打赏
  • 举报
回复
发一帖,看你们还讨论这么为。
bigcarrot7456 2012-04-30
  • 打赏
  • 举报
回复
关于阶乘的有难度一道题目
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2277
hit1er 2012-04-29
  • 打赏
  • 举报
回复
我日,好鸡巴混杂
加载更多回复(71)
西北工业大学NOJC程序设计习题答案(非本人制作,侵删) 1.“1“的传奇 2.A+B 3.A+BⅡ 4.AB 5.ACKERMAN 6.Arithmetic Progressions 7.Bee 8.Checksum algorithm 9.Coin Test 10.Dexter need help 11.Double 12.Easy problem 13.Favorite number 14.Graveyard 15.Hailstone 16.Hanoi Ⅱ 17.Houseboat 18.Music Composer 19.Redistribute wealth 20.Road trip 21.Scoring 22.Specialized Numbers 23.Sticks 24.Sum of Consecutive 25.Symmetric Sort 26.The Clock 27.The Ratio of gainers to losers 28.VOL大学乒乓球比赛 29.毕业设计论文打印 30.边沿与内芯的差 31.不会吧,又是A+B 32.不屈的小蜗 33.操场训练 34.插入链表节点 35.插入排序 36.插入字符 37.成绩表计算 38.成绩转换 39.出租车费 40.除法 41.创建与遍历职工链表 42.大数乘法 43.大数除法 44.大数加法 45.单词频次 46.迭代求根 47.多项式的猜想 48.二分查找 49.二分求根 50.发工资的日子 51.方差 52.分离单词 53.分数拆分 54.分数化小数 55.分数加减法 56.复数 57.高低交换 58.公园喷水器 59.韩信点兵 60.行程编码压缩算法 61.合并字符串 62.猴子分桃 63.火车站 64.获取指定二进制位 65.积分计算 66.级数和 67.计算A+B 68.计算PI 69.计算π 70.计算成绩 71.计算完全数 72.检测位图长宽 73.检查图像文件格式 74.奖金发放 75.阶乘合计 76.解不等式 77.精确幂乘 78.恐怖水母 79.快速排序 80.粒子裂变 81.链表动态增长或缩短 82.链表节点删除 83.两个整数之间所有的素数 84.路痴 85.冒泡排序 86.你会存钱吗 87.逆序整数 88.排列 89.排列分析 90.平均值函数 91.奇特的分数数列 92.求建筑高度 93.区间内素数 94.三点顺序 95.山迪的麻烦 96.删除字符 97.是该年的第几天 98.是该年的第几天? 99.数据加密 100.搜索字符 101.所有素数 102.探索合数世纪 103.特殊要求的字符串 104.特殊整数 105.完全数 106.王的对抗 107.危险的组合 108.文件比较 109.文章统计 110.五猴分桃 111.小型数据库 112.幸运儿 113.幸运数字”7“ 114.选择排序 115.寻找规律 116.循环移位 117.延伸的卡片 118.羊羊聚会 119.一维数组”赋值“ 120.一维数组”加法“ 121.勇闯天涯 122.右上角 123.右下角 124.圆及圆球等的相关计算 125.圆及圆球等相关计算 126.程序员添加行号 127.找出数字 128.找幸运数 129.找最大数 130.整数位数 131.重组字符串 132.子序列的和 133.子字符串替换 134.自然数立方的乐趣 135.字符串比较 136.字符串复制 137.字符串加密编码 138.字符串逆序 139.字符串排序 140.字符串替换 141.字符串左中右 142.组合数 143.最次方数 144.最大乘积 145.最大整数 146.最小整数 147.最长回文子串 148.左上角 149.左下角

69,364

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧