c的一个简单算发问题(100!的输出)

guanghi 2004-04-23 06:47:30
象100!是输出,pi的小数点后50位的输出等超过c一般数据类型的输出的保存是怎么实现的。
我看了几个例子 用的是数组。
可还是不怎么明白呀。
请给一个算法。
拜托!!!!!!!!!!!!!!!!!!!!
...全文
168 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
startlove 2004-07-27
  • 打赏
  • 举报
回复
这个是一个关于你输入的数的阶乘
主要方法是把数的乘写成加.并措一个数给来存放这个被乘数,不断的加.
并在结果的result中的第一个数是结果的位数,如.6!=720
在结果数组中是 3 0 2 7
这样存放的,
#include<stdio.h>
#include<malloc.h>
#define MAXN 1000
int pnext(int temp[],int k)
{
int *b,i,j,result,carry,m=temp[0];
b=(int *)malloc(sizeof(int)*(m+1));
for(i=1;i<=m;i++)
b[i]=temp[i];
for(j=1;j<k;j++)
{
for(carry=0,i=1;i<=m;i++)
{
result=(i<=temp[0]?temp[i]+b[i]:temp[i])+carry;
temp[i]=result%10;
carry=result/10;
}
if(carry) temp[++m]=carry;
}
free(b);
temp[0]=m;
return 0;
}
void write(int temp[],int k)
{
int i;
printf("%4d!=",k);
for(i=temp[0];i>0;i--)
printf("%d",temp[i]);
printf("\n\n");
}
int factorial(int temp[],int n)
{
int k;
temp[0]=1;
temp[1]=1;
for(k=2;k<=n;k++)
pnext(temp,k);
return 0;
}
int main()
{
int a[MAXN],n;
printf("Enter the number n: ");
scanf("%d",&n);
factorial(a,n);
write(a,n);
getch();
return 0;
}
sunjx119 2004-07-27
  • 打赏
  • 举报
回复
http://blog.csdn.net/sunjx119/archive/2004/07/22/48036.aspx
讲的很清楚了,去看看吧
snow810211 2004-07-27
  • 打赏
  • 举报
回复
#include <iostream.h>
#include <iomanip.h>
#include <stdlib.h>
#include <math.h>

int get_n();//input N;
int count_bit(int n);//計算n!所占的位數;
char *init(int size);//分配Heap memery,初始化數組;
void calc(char * a,int n);//calculate n!;
void display(char * a,int size);//display n!;


void main()
{
int n=get_n();
int size=count_bit(n);
char * pa=init(size);
cout<<"n = "<<n<<endl;
cout<<"size = "<<size<<endl;
calc(pa,n);
display(pa,size);
delete[]pa;

}

int get_n()
{
int n;
cout<<"Please input 'n' of n! n = ";
cin>>n;
while(n<0)
{
cout<<"input error!please input again! n = ";
cin>>n;
}
if(n==0)
exit(1);
return n;
}

int count_bit(int n)
{
double sum=1.0;
for(int i=1;i<=n;i++)
{
sum+=log10(i);
}
return (int)sum;
}

char * init(int size)
{
char * pa=new char[size];
if(pa==NULL)
{
cout<<"Too large factor of"<<size<<endl;
exit(1);
}
pa[0]=1;
for(int i=1;i<size;i++)
{
pa[i]=0;
}
return pa;
}

void calc(char * a,int n)
{
double current_bit=1;
long and_before=0;//前面低位的進位;
long and_next;//向高位的進位值;
for(int i=2;i<=n;i++)
{
int begin=0;
current_bit+=log10(i);//計算當前位數,沒有必要把數組中所有的元素都乘以i;
while(a[begin]==0)//如果當前位是0,就不計算;
{
begin++;
}
for(int j=0;j<(int)current_bit;j++)
{
int temp;
temp=i*a[j]+and_before;
a[j]=(char)(temp%10);
and_next=temp/10;
and_before=and_next;//本次向高位的進位就是下一次循環的and_before;
}
}
}


void display(char * a,int size)
{
int mark=0;
for(int i=size-1;i>=0;i--)
{
if(mark%50==0)
{
cout<<"\n第"<<setw(3)<<(mark/50+1)<<"個50位:";
}

cout<<(int)a[i];
mark++;
}
cout<<endl;
}




ppqbear 2004-07-27
  • 打赏
  • 举报
回复
好了
#include <iostream.h>
const int Longth=10000;
void doMove(int* result)
{
for(int i=1;i<Longth;i++)
{
if(result[Longth-i]>9)
{
int placeD=result[Longth-i]%10;
int moveD=result[Longth-i]/10;
result[Longth-i]=placeD;
result[Longth-i-1]+=moveD;
}
}
}

void fun(int* result,int MM)
{
for (int i=1;i<=Longth;i++) result[Longth-i]*=MM;
doMove(result);
}


int main()
{
int inputN;
cout<<"求大数阶乘,请输入一个整数:N=";
cin>>inputN;
int* const result=new int[Longth];
if (result==0)
{cout<<"数组过大,请减小Longth的值"<<endl;return 1;}

for (int i=0;i<Longth;result[i]=0,i++);
result[Longth-1]=1;

for (int ii=1;ii<=inputN;++ii) fun(result,ii);
int StartP;

for (int k=0;k<Longth;k++)
{
if(*(result+k))
{
StartP=k;
break;
}
}

cout<<"长度:"<<Longth-StartP<<endl;
for (int KK=StartP; KK<Longth;KK++) cout<<*(result+KK);
cout<<endl;
delete result;


}
ppqbear 2004-07-27
  • 打赏
  • 举报
回复
不好意思,最后的输出语句有错误,急了点!
ppqbear 2004-07-27
  • 打赏
  • 举报
回复
我写了一个,初次试水!

#include <iostream.h>
const int Longth=10000;
void doMove(int* result)
{
for(int i=1;i<Longth;i++)
{
if(result[Longth-i]>9)
{
int placeD=result[Longth-i]%10;
int moveD=result[Longth-i]/10;
result[Longth-i]=placeD;
result[Longth-i-1]+=moveD;
}
}
}

int* fun(int* result,int MM)
{
for (int i=1;i<=Longth;i++) result[Longth-i]*=MM;
doMove(result);
return result;
}
int main()
{
int inputN;
cout<<"求大数阶乘,请输入一个整数:N=";
cin>>inputN;
int* const result=new int[Longth];
if (result==0)
{cout<<"数组过大,请减小Longth的值"<<endl;return 1;}

for (int i=0;i<Longth;result[i]=0,i++);
result[Longth-1]=1;

for (int ii=1;ii<=inputN;++ii) fun(result,ii);

for (int k=0;k<Longth;k++)
{
if(*(result+k)) cout<<*(result+k);
}
cout<<endl;
delete result;
return(1);
}
ekschencn 2004-07-27
  • 打赏
  • 举报
回复
10000! ?会有人算这样的东西么?
如果真的要算,而且数组又不够大的话,那么可以试试step by step。就是算完某一段后保存,继续下一段的计算。还有就是,不要说10000!,就是100!的结果后面已经又很多的0了,考虑怎样处理一下可能有助于减少数组的大小(想法,没有实践过)。另外,可以尝试将数看成是2^32进制的,这样也可以减少数组的大小,而且比用10进制的效率更高(不过就是更难懂)
atommann 2004-07-27
  • 打赏
  • 举报
回复
;弄了一个函数
(defun wow(n)
(cond((eq n 0)1)
(t
(* n (wow(- n
1))))))

(wow 100)
或者改成一句话:
(defun wow(n)(cond((eq n 0)1)(T (* n (wow(- n 1))))))

(wow 12);运算结果就出错了
希望高手能帮我改一下,让它不溢出!
谢谢!
(wow 100)=93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
淡蓝冰 2004-07-27
  • 打赏
  • 举报
回复
以阶乘为例,它的算法和人手工计算差别不大。

用int数组来包装,可以采用先从低位到高位分别乘各个位置上的整数,处理结果直接存储在该位置上(i.e.每个位置上的数比一定就是个位数,可以是几十甚至上百),然后用一个统一的规整函数将上述处理数组规整化(i.e.将每一位上的数规整为个位数,其间用到取余和整除,像这样:data[i]+=data[i-1]/10; data[i-1]=data[i-1]%10; 做一个从低位到高位的循环就可以了。)
大致上就是这样的。

12l 2004-07-27
  • 打赏
  • 举报
回复
问题:
这个数组要多大?
如果变成了10000!的阶乘,有这么大的数组吗?
languagec 2004-04-24
  • 打赏
  • 举报
回复
哦,对了.
数是逆向存放的,方便相加.
比如12345+6789
在数组里是保存为54321和9876的,这样就可以从头到尾的加了.
languagec 2004-04-24
  • 打赏
  • 举报
回复
就是先写个长整数相加的子程序,再一次一次加.
比如说 n*100
就写个循环加99次,再加上自己本身.
算100! 还好,数一大就半天出不来了.
languagec 2004-04-24
  • 打赏
  • 举报
回复
我写过一个,效率甚低,但还算比较容易理解的.

#include "stdio.h"
#include "string.h"
void add(char *pf,char *ps)
{
char f,s;
int c,carry=0;
while(1)
{
if(*pf!='\0')
{
f=*pf;
pf++;
}
else f='0';

if(*ps!='\0')
{
s=*ps;
ps++;
}
else s='0';

c=(f-'0')+(s-'0')+carry;
carry=c/10;
*(pf-1)=c%10+'0';

if((*pf)=='\0'&&(*ps)=='\0')
{
if(carry!=0)
{
*pf='0'+carry;
*(++pf)='\0';
}
break;
}

}

}

void by(char *pf,char *ps,int n)
{
int step;
int i;
for(step=1;step<=n;step++)
{
for(i=0;i<step-1;i++)
{
add(pf,ps);
}
strcpy(ps,pf);

}
}


void turn(char *pf)
{
int f,l;
int i=0;
char *p;
char c;
for(p=pf;*p!='\0';p++)
i++;
printf("the length of the num is %d\n",i);
l=i-1;
for(f=0;f<l;l--,f++)
{
c=*(pf+f);
*(pf+f)=*(pf+l);
*(pf+l)=c;
}
}




main()
{
char pf[200]="1",ps[200]="0";
char c;
int i;
int j;
printf("gets num:");
scanf("%d",&i);
by(pf,ps,i);
printf("%s\n",pf);
printf("*************************\n");
turn(pf);
printf("%s\n",pf);
system("pause");
}
qbql 2004-04-24
  • 打赏
  • 举报
回复
你找一本c语言常用算法,有一部分是介绍万进制数的部分,其作用就是在计算机内存储朝大数和超高精度数,不过其思想和算法特别复杂,你有兴趣的话可以去看看,我做过存储一万位小数的程序,机子都快运行崩溃了。
yzb1000 2004-04-24
  • 打赏
  • 举报
回复
以前有一个专门讲这个得帖子
你可以搜一下“大整数”这个词
guanghi 2004-04-24
  • 打赏
  • 举报
回复
给一个实际程序可以吗 各位!!!!
palm99 2004-04-23
  • 打赏
  • 举报
回复
用数组,或链表自己设计递归算法 。
RookieStar 2004-04-23
  • 打赏
  • 举报
回复
以阶乘为例,它的算法和人手工计算差别不大。

用int数组来包装,可以采用先从低位到高位分别乘各个位置上的整数,处理结果直接存储在该位置上(i.e.每个位置上的数比一定就是个位数,可以是几十甚至上百),然后用一个统一的规整函数将上述处理数组规整化(i.e.将每一位上的数规整为个位数,其间用到取余和整除,像这样:data[i]+=data[i-1]/10; data[i-1]=data[i-1]%10; 做一个从低位到高位的循环就可以了。)
大致上就是这样的。
yonyon 2004-04-23
  • 打赏
  • 举报
回复
不太明白楼主的意图

69,371

社区成员

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

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