c语言程序设计报告超大数据的运算.docx
《c语言程序设计报告超大数据的运算.docx》由会员分享,可在线阅读,更多相关《c语言程序设计报告超大数据的运算.docx(25页珍藏版)》请在冰豆网上搜索。
![c语言程序设计报告超大数据的运算.docx](https://file1.bdocx.com/fileroot1/2023-6/13/9f040ad6-61e9-4615-b512-05cbe4645695/9f040ad6-61e9-4615-b512-05cbe46456951.gif)
c语言程序设计报告超大数据的运算
C语言课程设计报告
题目:
#1超大数据的运算
学院:
班级:
学生:
tax
学号:
提交日期:
目录
1、需求分析.....................................................3
1.题目要求........................................................3
2.限制条件及具体目标..............................................3
2、总体设计.....................................................3
1.完成过程........................................................3
2.问题与解决方法..................................................3
3.程序设计思想....................................................4
3、详细设计.....................................................5
1.函数列表........................................................5
2.函数关系调用图..................................................5
4、程序运行结果测试与分析....................................5
5、结论与心得...................................................9
附源代码............................................................9
1、需求分析
1.题目要求
对超大型数据(考虑负数和小数)进行存储、运算和输出打印。
运算具体要求如下:
1)进行四则运算;
2)整数型超大数据的阶乘;
3)超大型数据某范围内孪生质数的判断输出;
4)超大型数据文件的存储和读取。
2.限制条件及具体目标
1)将数据要求为超大型且考虑负数与小数,即各种数据类型都要考虑,并处理超出各种数据类型所能表示范围的数据;
2)运算要求包括四则运算、阶乘、孪生质数的判断;
3)程序要求支持文件的存储和读取。
二、总体设计
1.完成过程
本程序的目标是完成超大数据(以下简称大数)的运算,考虑负数和小数意味着数据类型要带符号并且包括浮点数据,所谓超大,即超出数据类型所能保存的范围,会发生溢出的情况,其次是大数的正常显示也无法通过一般数据类型实现,主要思想是利用字符串对大数进行保存,然后分析各种要求的四则运算,阶乘运算,孪生质数判断的过程,接下来模拟运算过程编写算法即可。
在各个算法的编写过程中插入文件的创建打开与写入,从而实现文件的存储和读取。
至此本程序的功能基本编写完成。
2.问题与解决方法
运算过程分析与模拟算法的编写本身比较复杂。
因为考虑负数的要求,就必须有判断符号的过程,体现在加减法的运算中,就要求程序要能根据符号的正负来选择运算方式,从而得出正确的结果,体现在乘除法的运算中,则判断是否异号进而决定计算结果的符号,并且在余数的计算中还有更复杂的进位分析,再加上考虑小数的要求,问题的复杂度就又提高一层,在乘除运算中,可以通过将浮点大数转换为整数,记录两数小数位数,计算得到的基础上再加上相应小数点即可。
在加减法中小数点位置不会改变,将小数点对齐后再进行运算即可。
阶乘运算在分析清算法后较容易实现,即实现循环的乘法。
孪生质数则通过接受要求范围后循环进行素数判断(利用根号)至循环结束即可。
3.程序设计思想
三、详细设计
1.函数列表
voidjianfa(inta[],intb[],intf)
voidjiafa(inta[],intb[],intf)
voidchengfa(inta[],intb[])
voidchufa(char*beichu,char*chu,char*shang,char*yu)
voidsi_ze()
voidjie_cheng()
voidluansheng_zhishu()
intmain()
2.函数的调用关系图
4、程序运行结果测试与分析
经大量具代表性的数据测试,本程序已能实现预期功能,符合课程题目要求,能实现超大数据的四则运算、阶乘运算以及范围内孪生质数的判断输出,并将数据存储到指定文件中,程序演示效果如下:
表格1四则运算演示
表格2阶乘计算演示
表格3孪生质数演示
表格4数据文件存储演示
五、结论与心得
我主要负责阶乘运算的实现,并和小组成员一起实现其他运算功能
1、刚开始考虑进位问题过于简单,导致测试数据时多次出错;
2、分析运算方式并将其编写为算法的过程中花费了很大的功夫理解和编写,发现自己的编程思维还有待提升;
3、开始写程序时源程序没有严格按单元模块结构编写,可读性较差。
4、由于初次进行大规模的程序设计,层次结构划分不太合理,应在以后的设计中强化此思维,逐渐与高效简练的程序设计接轨。
附源代码如下
#include
#include
#include
#include
#include
#defineMAX101
#defineN1000
#defineM250000
/*函数功能:
利用字符串实现超长数加减法运算*/
voidjianfa(inta[],intb[],intf);
intlena,lenb,da=1,db=1;/*把lena,lenb设为全局变量,lena纪录第一个超长型数组的位数,lenb纪录第二个超长型数组的位数*/
charb1[MAX],b2[MAX];/*纪录需要计算的两个超长型数据*/
voidinput(inta1[],inta2[])/*函数input为输入函数,用来纪录两个待计算的超型数据,以数组首地址为参数.以实现返回两个超长型数据*/
{
FILE*fp1;
if((fp1=fopen("xxx.txt","a+"))==NULL)
{printf("\ncannotcreat!
");
exit(0);
}
inti,fa=1,fb=1;
printf("请输入第一个数:
\n");
scanf("%s",b1);
fputs(b1,fp1);
fputs(",",fp1);
printf("请输入第二个数:
\n");/*输入两个超长型数据*/
scanf("%s",b2);
fputs(b2,fp1);
lena=strlen(b1);/*lena纪录b1的位数*/
lenb=strlen(b2);/*lenb纪录b2的位数*/
if(b1[0]=='-'){lena--;da=-1;fa=0;}/*判断数组的符号*/
if(b2[0]=='-'){lenb--;db=-1;fb=0;}
for(i=0;ifor(i=0;i}
voidjiafa(inta[],intb[],intf)/*超长型数据加法运算*/
{
FILE*fp1;
inti,c[MAX+1]={0},s;
if((fp1=fopen("xxx.txt","a+"))==NULL)
{printf("\ncannotcreat!
");
exit(0);
}
if(da*db>0||f)
{
if(lena>lenb)s=lena;
elses=lenb;/*用s纪录结果的最大位数*/
for(i=0;i
{
c[i]=a[i]+b[i]+c[i];
c[i+1]=(int)c[i]/10;/*c[i+1]代表进位*/
c[i]=(int)c[i]%10;/*超长数加法运算过程*/
}
if(c[s])s++;/*判断最后结果的位数*/
fputs("\n两者之和:
\n",fp1);
if(da<0&&f||da<0){printf("-");fputc('-',fp1);}
for(i=s-1;i>=0;i--)
{printf("%d",c[i]);fprintf(fp1,"%d",c[i]);}/*输出结果*/
}
elsejianfa(a,b,1);
}
voidjianfa(inta[],intb[],intf)/*超长数减法运算*/
{
FILE*fp1;
inti,u=0,c[MAX+1]={0},s;
if((fp1=fopen("xxx.txt","a+"))==NULL)
{printf("\ncannotcreat!
");
exit(0);
}
fputs("\n两者之差:
\n",fp1);
if(da*db>0||f)
{
if(lena>lenb)s=lena;
else/*用s纪录结果的最大位数*/
{s=lenb;
for(i=s;a[i]<=b[i]&&i>=0;i--)
if(a[i]
}
if(!
u)/*超长数减法运算过程*/
for(i=0;i
{
if(a[i]
{a[i+1]--;
a[i]+=10;
}
c[i]=a[i]-b[i];
}
else/*当a
for(i=0;i
{
if(b[i]{b[i+1]--;
b[i]+=10;
}
c[i]=b[i]-a[i];
}
while(!
c[s-1]&&s>1)s--;/*判断最后结果的位数*/
if(f&&(da>0&&u||da<0&&!
u)||da>0&&(db>0&&u||u&&!
f)){printf("-");fputc('-',fp1);}
if(da<0&&db<0&&!
u){printf("-");fputc('-',fp1);}/*如果u为真是输出负号*/
for(i=s-1;i>=0;i--){printf("%d",c[i]);fprintf(fp1,"%d",c[i]);}
}
elsejiafa(a,b,1);
}
/*超长型数据乘除法运算*/
voidchengfa(inta[],intb[])/*超长数乘法运算*/
{
FILE*fp1;
inti,j,c[2*MAX]={0},s;
s=lena+lenb-1;/*用s纪录结果的最大位数*/
if((fp1=fopen("xxx.txt","a+"))==NULL)
{printf("\ncannotcreat!
");
exit(0);
}
fputs("\n两者之积:
\n",fp1);
for(i=0;ifor(j=0;j{
c[i+j]=a[i]*b[j]+c[i+j];
c[i+j+1]=c[i+j]/10+c[i+j+1];
c[i+j]=c[i+j]%10;
}
while(!
c[s])s--;/*判断最后结果的位数*/
if(da*db<0){printf("-");fputc('-',fp1);}
for(i=s;i>=0;i--){printf("%d",c[i]);fprintf(fp1,"%d",c[i]);}/*输出结果*/
}
//比较两个用字符串存储的超长数的大小,若a>b,返回1;a==b,返回0;a
intCompare(constchar*a,constchar*b)
{
intlenA=strlen(a);
intlenB=strlen(b);
if(a[0]=='-')lenA--;
if(b[0]=='-')lenB--;
if(lenA!
=lenB)
returnlenA>lenB?
1:
-1;
else
returnstrcmp(a,b);
}
//超长正数的减法,且被减数大于减数
voidcha(char*beijian,char*jian,char*chas)
{
intcB[MAX]={0};//用来存储被减数的整型数组
intcJ[MAX]={0};//用来存储减数的整型数组
intcC[MAX]={0};//用来存储两数之差的整型数组
intlenM=strlen(beijian),lenS=strlen(jian);//被减数和减数字符串的长度
inti;
//逆序复制减数和被减数到整型数组(因为减法运算是从低位开始),保证cB大于cJ
for(i=0;icB[i]=beijian[lenM-1-i]-'0';
for(i=0;icJ[i]=jian[lenS-1-i]-'0';
for(i=0;i{
if(cB[i]>=cJ[i])//被减数大于减数,直接相减
cC[i]=cB[i]-cJ[i];
else//否则要向前借位
{
cC[i]=cB[i]+10-cJ[i];
--cB[i+1];
}
}
while(cC[i-1]==0)
i--;
intj=0;
intk;
for(k=i-1;k>=0;k--,j++)//逆序存储两数之差到字符串chas
chas[j]=cC[k]+'0';
chas[j]='\0';
}
voidchufa(char*beichu,char*chu,char*shang,char*yu)//超长型数据的整除,求余运算
{
intlenv=strlen(beichu),lens=strlen(chu);
if(beichu[0]=='-')
{
da=-1;//判断数组的符号
for(inti=0;i{
beichu[i]=beichu[i+1];
}
lenv--;
}
if(chu[0]=='-')
{
db=-1;
for(inti=0;i{
chu[i]=chu[i+1];
}
lens--;
}
if(Compare(beichu,chu)==0)//被除数等于除数
{
strcpy(shang,"1");
strcpy(yu,"0");
return;
}
if(strcmp(chu,"0")==0||Compare(beichu,chu)<0)//被除数小于除数
{
strcpy(shang,"0");
strcpy(yu,beichu);
return;
}
charbuf[2]="0";//临时数组依次存储被除数的每一位数
inti,s,k;
strcpy(yu,"");//先使余数的值为空
for(i=0,k=0;beichu[i]!
='\0';i++)
{
s=0;
buf[0]=beichu[i];
strcat(yu,buf);//接上被除数的一位数,改变当前余数
while(Compare(yu,chu)>=0)//连减试商
{
s++;
cha(yu,chu,yu);
}
shang[k++]=s+'0';//记录每一位得到的商值
if(strcmp(yu,"0")==0)
strcpy(yu,"");//使余数的值为空,去掉多余的0
}
shang[k]='\0';//去掉多余的0
intj;
for(i=0;shang[i]=='0';i++)
;
for(j=i;j<=k;j++)
shang[j-i]=shang[j];
}
voidput_chufa()
{
FILE*fp1;
if((fp1=fopen("xxx.txt","a+"))==NULL)
{printf("\ncannotcreat!
");
exit(0);
}
charc[MAX]={0},d[MAX]={0};
chufa(b1,b2,c,d);
puts("两者之商:
");
fputs("\n两者之商:
\n",fp1);
if(da*db<0&&strcmp(c,"0")){printf("-");fputc('-',fp1);}
puts(c);
fputs(c,fp1);
puts("余数:
");
fputs("\n余数:
\n",fp1);
puts(d);
fputs(d,fp1);
fputc('\n',fp1);
}
voidsi_ze()
{
inta[MAX]={0},b[MAX]={0};
input(a,b);
printf("\n两者之和:
\n",b1,b2);jiafa(a,b,0);
printf("\n两者之差:
\n",b1,b2);jianfa(a,b,0);
printf("\n两者之积:
\n",b1,b2);chengfa(a,b);
printf("\n");
getchar();
put_chufa();
}
/*超大数阶乘运算*/
voidjie_cheng()
{
FILE*fp1;
charc='\n';
intn;
inti,j;
inta[M];//存数运算结果
intp,h;//p存储当前结果的位数,h为进位
a[1]=1;
printf("输入所要求的整数:
");
scanf("%d",&n);
if((fp1=fopen("xxx.txt","a+"))==NULL)
{printf("\ncannotcreat!
");
exit(0);
}
fputs("\n阶乘:
\n",fp1);
p=1;
for(i=2;i<=n;i++)//循环与2,3,4.....n相乘
{
for(j=1,h=0;j<=p;j++)//让a[]的每位与i相乘
{
a[j]=a[j]*i+h;
h=a[j]/10;
a[j]=a[j]%10;
}
while(h>0)//如果h不为0
{
a[j]=h%10;
h=h/10;
j++;
}
p=j-1;//将当前的位数赋给p
}
printf("%d!
=",n);
fprintf(fp1,"%d",n);
fputs("!
=",fp1);
for(i=p;i>=2;i--)
{
printf("%d",a[i]);
fprintf(fp1,"%d",a[i]);
}
printf("%d\n",a[i]);
fprintf(fp1,"%d",a[i]);
fputc(c,fp1);
fclose(fp1);
}
/*超大数据范围内孪生质数的输出*/
intprime(longintn)
{
longintr,i;
r=(int)sqrt(n);
for(i=2;i<=r;i++)
{
if(n%i==0)//此处n%i==0,说明不是素数,立刻跳出循环
return0;
}
return1;
}
voidluansheng_zhishu()
{
FILE*fp1;
longintm,n,i,t=0;
if((fp1=fopen("xxx.txt","a+"))==NULL)
{printf("\ncannotcreat!
");
exit(0);
}
printf("请输入范围m,n\n");
scanf("%d%d",&m,&n);
fprintf(fp1,"%d",m);
fputc('~',fp1);
fprintf(fp1,"%d",n);
fputc('\n',fp1);
fputs("范围内孪生质数有:
\n",fp1);
for(i=m;i<=n-2;i++)//此处限制i<=n-2,不然prime(i+2)超过范围;另外i每次自加1,//不能加2
{
if(prime(i)&&prime(i+2))
{
t+=1;
printf("(%d,%d)\n",i,i+2);
fputc('(',fp1);
fprintf(fp1,"%d",i);
fputc(',',fp1);
fprintf(fp1,"%d",i+2);
fputc(')',fp1);
fputc('\n',fp1);
}
}
printf("%d\n",t);
fprintf(fp1,"%d",t);
fputc('\n',fp1);
if(t==0)
{printf("无孪生素数!
");//这个输出格式应该在循环外判定
fputs("无孪生素数!
",fp1);}
//getch();
}
/*主函数*/
intmain()
{
intn;
printf("选择想要进行的运算:
1、四则运算,2、阶乘,3、孪生