最小的计算大数阶乘的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的阶乘

...全文
6121 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)

69,373

社区成员

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

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