资源描述
设计题目: 大整数的四则运算
1。 功能简介:编写出实现大整数之间相加,相减,相乘,相除的程序,并输出计算结构。
课程设计要求:采用模块化程序设计
源程序中应有足够的注释
必须上机调试通过
注重算法运用,优化存储效率与运算效率
需提交源程序(含有注释)及相关文件(数据或数据库文件);
提交设计报告书.
2. 总体结构:
数据初始化
判断运算符号
加法
正整数
非正整数
转变为正整数
减法
转变为加法
乘法
除法
转变为乘法和减法
退出
流程图:
3 。概要设计:
1) 加法运算
利用两个整形数组分别存放两个数a和b的每一位的数值,最低位存放符号。如果a和b同号,从最低为开始计算,如果有进位则保存在高一位,本为则减10,然后反序将计算后的各个位的数值保存在一个数组c并输出,如果a和b都是负数则在前面要输出负号,函数的返回值为c的位数。如果a和b异号,也即两个正整数相减,从最低位开始相减,如果要借位则本位加10再相减,高一位要减1,然后反序将计算后的各个位的数值保存在一个数组c并输出,在前面要输出相应的符号位。
2) 减法运算
可将减法运算转化为加法运算,只要将被减数的符号改变即可。
3) 乘法运算
符号存放在最低位,将其中一个数a的每一位分别乘以另一个数b的每一位,并将结果保存在数组c中,然后重复计算a的下一位跟b的每一位的乘积,把上一次计算保存在c的值加上本次计算后的值,并保存在c自身中,直到a的最高位,最后输出符号和相应的计算结果。
4) 除法运算
利用乘法和减法,将除数分别乘以1到9,直到其值大于等于被除数的对应的数,然后被除数对应的数减去其乘积,保存在一个数组中,下一次循环把它归到被除数中继续做除法运算,最后得到余数并输出。
4. 函数功能:
1. void init(int a[],int b[],int *p1,int *p2)
2. 功能说明:读入所要计算的数值,数据初始化
3. int plus(int a[],int b[],int c[],int m,int n)
4. 功能说明:两个正整数相加
3。 void change(int a[],int b[],int m,int n)
功能说明:当两异号数相加时,改变其符号以符合加法运算
5. int minus(int a[],int b[],int d[],int m,int n)
6. 功能说明:两个正整数相减
5. void minusfun(int a[],int b[],int d[],int m,int n)
功能说明:判断两个异号数的相加方式
7. int multi(int a[],int b[],int c[],int m,int n)
8. 功能说明:两个正整数相乘
7. void print(long c[],int flag)
功能说明:打印带符号flag(1为负)的long c[]数组
8。 int write(long a[],int flag)
功能说明:将键盘敲入的数字按4位一组放入long a[],且将符号放入flag
9。 void mul(long a[],int first,int last,long b[],long c[])
功能说明:乘法,a的第last到first位乘以b,答案放到c
10。 int compara(long a[],int first,int last,long b[])
功能说明:比较数组a,b大小,first last分别为a的最高最低位
11。 int minusd(long a[],int first,int last,long b[],long c[],int flag)
功能说明:a为被减数,first last为a最高最低位,b为减数,c为差,flag为符号
12。 void div(long a[],long b[],long c[],int fa)
功能说明:除法,a除以b的值放入c,fa为a符号
13。 void menu()
功能说明:打印菜单函数
14。 void main()
功能说明:主函数,调用其余函数,计算相应功能的值并输出.
5。源程序:
#include<iostream。h〉
#include〈math。h>
#include〈stdio。h〉
#define MAX 40 //可以修改,此时最大运算位数为四十位
#define N 10 //此处应为最大位数除以4
void init(int a[],int b[],int *p1,int *p2) //输入
{
int i,j;
char r,s;
for(i=0;i〈MAX;i++)
{
a[i]=0;
b[i]=0;
}
printf(”请输入处理的第一个数的值:”);
r=getchar();
if(r==45)
{
a[0]=r;
for(i=1;(r=getchar())!=’\n’;i++)
a[i]=r-48;
}
else
{
a[1]=r-48;
for(i=2;(r=getchar())!='\n’;i++)
a[i]=r—48;
}
*p1=i;
printf(”请输入处理的第二个数的值:");
s=getchar();
if(s==45)
{
b[0]=s;
for(j=1;(s=getchar())!='\n’;j++)
b[j]=s—48;
}
else
{
b[1]=s—48;
for(j=2;(s=getchar())!='\n';j++)
b[j]=s-48;
}
*p2=j;
}
int plus(int a[],int b[],int c[],int m,int n) //加法运算
{
int d[MAX]={0},i,j,k;
for(i=0;i<MAX;i++) c[i]=0;
if(a[1]==0)
{
for(i=0;i〈n;i++) c[i]=b[i];
return(i);
}
if(b[1]==0)
{
for(i=0;i〈m;i++) c[i]=a[i];
return(i);
}
for(i=m-1,j=n—1,k=1;i>0&&j〉0;i——,j——,k++)
{
d[k]=a[i]+b[j]+d[k];
if(d[k]>9)
{
d[k+1]++;d[k]=d[k]—10;}
}
while(i〉0)
{
d[k]=d[k]+a[i];
if(d[k]〉9)
{
d[k+1]++;d[k]=d[k]-10;
}
k++;
i--;
}
while(j〉0)
{
d[k]=d[k]+b[j];
if(d[k]〉9)
{
d[k+1]++;d[k]=d[k]-10;
}
k++;
j——;
}
d[0]=a[0]+b[0];
c[0]=d[0];
if(d[k]==0)
k—-;
for(i=1;k〉0;i++,k--)
c[i]=d[k];
return(i);
}
void change(int a[],int b[],int m,int n) //变号运算
{
int i,j;
int c[MAX];
if(m〈=n&&b[0]==45)
{
for(i=1;i〈m;i++)
c[i]=a[i];
for(i=1,j=1;j〈n;i++,j++)
a[i]=b[j];
for(i=1,j=1;j<n;i++,j++)
b[i]=c[j];
for(j=i;j〈MAX;j++)
b[j]=0;
return;
}
if(m>=n&&a[0]==45)
{
a[0]=0;
b[0]=45;
return;
}
}
int minus(int a[],int b[],int d[],int m,int n) //减法运算
{
int c[MAX]={0},i,j,k;
for(i=0;i〈MAX;i++)
d[i]=0;
for(i=m-1,j=n-1,k=1;i>0&&j>0;i——,j—-,k++)
{
if(c[k]〈0||a[i]〈b[j])
{
c[k]=c[k]+a[i]—b[j];
if(c[k]〈0)
{
c[k]+=10;
c[k+1]-—;
}
}
else c[k]=a[i]—b[j];
}
while(i〉0)
{
c[k]=c[k]+a[i];
if(c[k]〈0)
{
c[k]+=10;
c[k+1]—-;
}
k++;i—-;
}
c[k]=a[i]+c[k];
while(c[k]〈=0&&k〉0)
k-—;
for(i=1;k>0;i++)
d[i]=c[k-—];
return(i);
}
void minusfun(int a[],int b[],int d[],int m,int n) //判断是否两异号数相加
{
int i,j,f=0,g=0;
if(a[1]==0)
{
if(b[0]!=0) printf(”—”);
for(i=1;i〈n;i++)
printf(”%d”,b[i]);
printf("\n”);
return;
}
if(b[1]==0)
{
if(a[0]!=0)
printf(”-");
for(i=1;i<m;i++)
printf(”%d”,a[i]);
printf("\n”);
return;
}
if(m==n)
{
for(i=1;i〈m;i++)
{
if((a[i]<b[i]&&b[0]==45)||(a[i]>b[i]&&a[0]==45))
g=1;
if(a[i]!=b[i]) f=1;
}
if(f==0)
{
printf("0\n”);
return;
}
if(g==1)
{
change(a,b,m,n);
printf(”—”);
j=minus(a,b,d,n,m);
for(i=1;i〈j;i++) printf(”%d”,d[i]);
printf(”\n”);return;
}
else if(a[0]==45&&b[0]==0)
{
j=minus(b,a,d,n,m);
for(i=1;i〈j;i++)
printf(”%d”,d[i]);
printf("\n”);
return;
}
else
{
j=minus(a,b,d,m,n);
for(i=1;i〈j;i++)
printf(”%d”,d[i]);
printf(”\n”);return;
}
}
if(m〉n&&b[0]==45)
{
j=minus(a,b,d,m,n);
for(i=1;i〈j;i++) printf(”%d”,d[i]);
printf(”\n”);return;
}
if(m<n&&b[0]==45)
{
change(a,b,m,n);
printf(”-”);
j=minus(a,b,d,n,m);
for(i=1;i<j;i++)
printf(”%d”,d[i]);
printf(”\n”);
return;
}
if(m〉n&&a[0]==45)
{
change(a,b,m,n);
printf("—”);
j=minus(a,b,d,m,n);
for(i=1;i<j;i++)
printf("%d”,d[i]);
printf(”\n”);
return;
}
if(m〈n&&a[0]==45)
{
j=minus(b,a,d,n,m);
for(i=1;i<j;i++)
printf(”%d”,d[i]);
printf(”\n”);
return;
}
}
int multi(int a[],int b[],int c[],int m,int n) //正整数乘法运算
{
int d[MAX]={0},e[MAX]={0},i,j,k,r,s,x,y;
for(i=0;i<MAX;i++)
c[i]=0;
if(m〈=n)
{
for(i=m—1,s=1;i〉0;i--,s++)
{
for(r=0;r〈MAX;r++){d[r]=0;e[r]=0;}
for(j=n-1,k=1*s;j〉0;j-—,k++)
{
d[k]=a[i]*b[j]+d[k];
if(d[k]〉9) {d[k+1]=d[k+1]+d[k]/10;d[k]=d[k]%10;}
}
if(d[k]==0)
k——;
y=k;
for(r=1;k〉0;r++,k—-)
e[r]=d[k];
for(r=1;r<MAX;r++)
d[r]=e[r];
if(s==1)
x=plus(c,d,e,0,y+1);
else
x=plus(c,d,e,y,y+1);
for(r=0;r<MAX;r++)
c[r]=e[r];
}
}
else if(m>n)
{
for(j=n—1,s=1;j>0;j——,s++)
{
for(r=0;r<MAX;r++)
{
d[r]=0;e[r]=0;
}
for(i=m-1,k=1*s;i〉0;i—-,k++)
{
d[k]=a[i]*b[j]+d[k];
if(d[k]〉9)
{
d[k+1]=d[k+1]+d[k]/10;
d[k]=d[k]%10;
}
}
if(d[k]==0)
k--;
y=k;
for(r=1;k>0;r++,k--)
e[r]=d[k];
for(r=1;r〈MAX;r++)
d[r]=e[r];
if(s==1)
x=plus(c,d,e,0,y+1);
else
x=plus(c,d,e,y,y+1);
for(r=0;r<MAX;r++)
c[r]=e[r];
}
}
return(x);
}
void print(long c[],int flag) //输出
{
int i;
for(i=N-1;i〉=0;i——)
if(c[i])
break;
if(flag)
printf("—”);
printf(”%4d",c[i——]);
for(;i〉=0;i-—)
{
if(c[i]/1000)
printf(" %4ld”,c[i]);
else if(c[i]/100)
printf(" 0%3ld”,c[i]);
else if(c[i]/10)
printf(” 00%2ld”,c[i]);
else
printf(” 000%1ld”,c[i]);
}
}
int write(long a[],int flag) //将键盘敲入的数字按4位一组放入long a[],且将符号放入flag
{
char num[N*4];
char temp;
int i,j,k;
for(i=0;i<N*4;i++)
{
num[i]=getchar();
if(num[i]==10)
{
i-—;
break;
}
if(num[i]==45)
{
flag=(flag+1)%2;
i--;
}
}
k=0;
for(j=0;j〈=i/2;j++)
{
temp=num[j];
num[j]=num[i—k];
num[i-k]=temp;
k++;
}
k=1;
for(j=0;j<=i;j++)
switch(k)
{
case 1:a[j/4]+=(long)(num[j]—48);
k++; break;
case 2:a[j/4]+=(long)(num[j]—48)*10;
k++; break;
case 3:a[j/4]+=(long)(num[j]—48)*100;
k++; break;
case 4:a[j/4]+=(long)(num[j]-48)*1000;
k=1; break;
}
return flag;
}
void mul(long a[],int first,int last,long b[],long c[]) //乘法
{
int i,j;
int max_i;
long temp;
for(max_i=N—1;max_i>=0;max_i——)
if(b[max_i])
break;
for(i=0;i〈=max_i;i++)
if(b[i])
for(j=first;j〈=last;j++)
{
temp=a[j]*b[i];
c[i+j—first]+=temp%10000;
c[i+j-first+1]+=((temp/10000)+(c[i+j—first]/10000));
c[i+j—first]=c[i+j—first]%10000;
}
}
int compara(long a[],int first,int last,long b[]) //比较数组a,b大小
{
int flag=2;
int i;
int k=0;
int len;
for(len=N—1;len〉=0;len--)
if(b[len])
break;
if((first—last)>=len)
{
if((first-last)>len)
flag=1;
else
for(i=len;i>=0;i-—)
{
if(a[first—k]>b[i])
{
flag=1;
break;
}
if(a[first—k]<b[i])
{
flag=0;
break;
}
k++;
}
}
else
flag=0;
return
flag;
}
int minusd(long a[],int first,int last,long b[],long c[],int flag)
{
int notchange;
int i,k=0;
int max;
notchange=compara(a,first,last,b);
if(notchange)
{
for(i=last;i〈=first;i++)
{
if(a[i]〈b[k])
{
a[i]+=10000;
a[i+1]-—;
}
c[i]=a[i]—b[k];
k++;
}
}
else
{
flag=(flag+1)%2;
for(max=N-1;max〉=0;max--)
if(b[max])
break;
for(i=0;i〈=max;i++)
{
if(b[i]〈a[last+k])
{
b[i]+=10000;
b[i+1]--;
}
c[i]=b[i]—a[last+k];
k++;
}
}
return flag;
}
void div(long a[],long b[],long c[],int fa) //除法
{
long result[N+1]={0};
int len_a;
int k;
int i;
printf(”\n");
print(a,fa);
for(len_a=N—1;len_a>=0;len_a——)
if(a[len_a])
break;
k=len_a;
while(compara(a,len_a,0,b))
{
while(!compara(a,len_a,k,b))
k-—;
c[k]=1;
mul(c,k,k,b,result);
while(compara(a,len_a,k,result)){
c[k]++;
for(i=N—1;i>=0;i--)
result[i]=0;
mul(c,k,k,b,result);
}
c[k]-—;
for(i=N-1;i〉=0;i--)
result[i]=0;
mul(c,k,k,b,result);
minusd(a,len_a,k,result,a,0);
for(i=N—1;i〉=0;i——)
result[i]=0;
for(len_a=N-1;len_a〉=0;len_a-—)
if(a[len_a])
break;
k=len_a;
}
}
void menu() //菜单
{
printf("==================================大整数计算器==================================”);
printf("1。加法2.减法3。乘法4.除法0。退出\n”);
printf(”请从1~4中选择:”);
return;
}
void main() //主函数
{
int flag;
int max;
int fa;
int fb;
long ad[N],bd[N],cd[2*N];
int a[MAX]={0},b[MAX]={0},c[MAX]={0},d[MAX]={0};
char s;
int m,n,i,j;
int *p1,*p2;
p1=&m;
p2=&n;
menu();
s=getchar();
getchar();
while(1)
{
switch(s)
{
case ’0':
return;
case '1’:
printf("格式为:a+b\n”);
init(a,b,p1,p2);
if(a[1]==0&&b[1]==0)
{
printf("结果是:a+b=0\n”);
break;
}
if(a[0]==b[0])
{
j=plus(a,b,c,m,n);
printf(”结果是:a+b=”);
if(c[0]!=0)
printf(”—”);
for(i=1;i〈j;i++)
printf(”%d”,c[i]);
}
else
{
printf("结果是:a+b=");
minusfun(a,b,d,m,n);
}
printf(”\n”);
break;
case '2':
printf(”格式为:a—b\n”);
init(a,b,p1,p2);
if(b[0]==0)
b[0]=45;
else if(b[0]==45)
b[0]=0;
if(a[1]==0&&b[1]==0)
{
printf(”结果是:a—b=0\n");
break;
}
if(a[0]==b[0])
{
j=plus(a,b,c,m,n);
printf(”结果是:a-b=”);
if(c[0]!=0)
printf(”-");
for(i=1;i<j;i++)
printf(”%d”,c[i]);
}
else
{
printf(”结果是:a—b=");
minusfun(a,b,d,m,n);
}
printf(”\n");
break;
case ’3':
init(a,b,p1,p2);
if(a[1]==0||b[1]==0)
{
printf("结果是:0\n”);
break;
}
j=multi(a,b,c,m,n);
printf("结果是:");
if((a[0]==45&&b[0]==0)||(b[0]==45&&a[0]==0))
printf("—”);
for(i=1;i〈j;i++)
printf(”%d",c[i]);
printf(”\n”);
break;
case '4’:
flag=fa=fb=0;
for(max=0;max<N;max++)
ad[max]=bd[max]=cd[max]=0;
printf(”请输入被除数:");
fa=write(cd,fa);
printf("\n请输入除数:");
fb=write(bd,fb);
div(cd,bd,ad,fa);
flag=(fa+fb)%2;
printf(” / ");
print(bd,fb);
printf(” = ”);
print(ad,flag);
printf(”(");
print(cd,0);
printf(")\n");
break;
}
menu();
s=getchar();
getchar();
}
}
6.调试结果
程序的调试是指对程序的差错和排错,为了便于差错、阅读,在设计该程序的过程中添加了尽可能多的注释,这就为接下来的调试过程带来了很多方便. 经过仔细检查之后进行上机调试。进行编译,如果在编译和连接过程中发现错误,屏幕上显示了出错信息,根据提示找到出错的位置,加以改正,在进行编译……如此反复,直到顺利通过编译和连接为止。
以下是编译的最终结果:
由上图可知,该程序可以成功运行,且运行结果正确无误。
7.设计总结:
此次程序设计过程中发现的主要问题有三:
1) 语法错误 :大多的语法错误在通过书本参考下能够修改。主要是平时缺乏锻炼、不太注意而产生的。如没有注意具体数据使用是有一定的范围限定;过分重视分号的重要性而在for、if、while语句中画蛇添足加分号.
2)注释的位置 :程序设计中在注释的时候不能同我们平常写字一样随心所欲,我们应该注意注释的格式。注释中不能含有C语言可执行的语句.
3)技术问题:编写到最后不会除法的算法,就上网借鉴了下,应该记住以备将来使用。
8。心得体会及致谢:
经过这次困难重重的C语言编程设计,我学到了更多的编程技巧,同时也对C有了更多的认识.通过这次两个星期左右的C语言程序课程设计实习,我觉得我学到了很多,以前在课堂上学的东西以为都是一些枯燥无味的东西,可是操作在实践中的时候发现其实也有别样的魅力所在,变得生动活泼而有挑战性。同时也让我感觉到自己编程的能力还有很多不足,希望在以后的学习生活中能有更多的机会进行提高.最后也感谢郭恒宁老师的指导。
展开阅读全文