代码储存,大数四则运算
翻转课堂
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int v[10005]={0};//全局变量作为输出
int add(int *a,int *b,int lena,int lenb)
{int j,len1,len2,length,digit=0;
if(lena>lenb)
length=lena;
else
length=lenb;
for(j=0;j<=length;j++){
v[j]=a[j]+b[j]+digit;
digit=0;
if(v[j]>=10){ //进位
v[j]=v[j]-10;
digit=1;
}
}
if(v[j-1]==0)//判断位数是否+1
j=j-2;
else
j--;
return j;//返回和的位数
}
int mil(int *a,int *b,int lena,int lenb)
{int j,len1,len2,length,digit=0,fuhao;
if(lena==lenb){//比较两个数大小,判断a-b还是b-a
for(j=lena-1;j>=0;j--){
if(a[j]>b[j]){
fuhao=1;
break;
}
if(a[j]<b[j]){
fuhao=-1;
break;
}
if(a[j]==b[j]){
if(j==0){
return j=0;
break;
}
continue;
}
}
}
if(lena>lenb||fuhao==1){
length=lena;
for(j=0;j<length;j++){
v[j]=a[j]-b[j]+digit;//按位减,不够借位
digit=0;
if(v[j]<0){
v[j]+=10;
digit=-1;
}
}
if(v[j-1]==0)
j=j-2;
else j=j-1;
while(v[j]==0){
j--;
}
j++;
v[j]=-2;
return j;
}
if(lena<lenb||fuhao==-1){
length=lenb;
for(j=0;j<length;j++){
v[j]=b[j]-a[j]+digit;
digit=0;
if(v[j]<0){
v[j]+=10;
digit=-1;
}
}
if(v[j-1]==0)
j=j-2;
else j=j-1;
while(v[j]==0){
j--;
}
j++;
v[j]=-1;
return j;
}
}
int mul(int *a,int *b,int lena,int lenb)
{int i;
int j=0;
if(a[lena-1]==0||b[lenb-1]==0)
{j=0;
return j; }//判断一方为零的情况并返回位数1
else
{
for(i=0;i<=lena+lenb;i++)
v[i]=0;
for(i=0;i<lena;i++)
for(j=0;j<lenb;j++)
{
v[i+j]+=a[i]*b[j];
} //模拟手算过程 将项的和保存起来 可以自己手算找一下规律
for(i=0;i<=lena+lenb;i++)
{
if(v[i]>=10)
{
v[i+1]+=v[i]/10;
v[i]=v[i]%10;
}//将大于十的项进位
}
if(v[lena+lenb-1]==0)
j=lena+lenb-2;
else
j=lena+lenb-1;
return j;}}//两个非零数相乘,其位数必为它们的位数相加或相加减一,此处判断第lena+lenb项的值,若为零则位数为lena+lenb-1;反之同理。}}
int div(int *a,int *b,int lena,int lenb)
{
int i,u,j,p,digit=0,ok=1,n,m;
int c[10001]={0};
if(lena<lenb)
return -1;
if(lena==lenb)
for(i=lena-1;i>=0;i--)
{
if(a[i]>b[i])
break;
else if(a[i]<b[i])//判断相除是否大于0
return -1;
}
for(i=lena-lenb;i>=0;i--)
{if(i>=2)//位数相差太大直接除以pow(10,n)倍
{memset(c,0,sizeof(c));
for(u=lenb-1;u>=0;u--)//右移翻倍
c[u+i-1]=b[u];
while(1){ok=1;
for(j=lena;j>=0;j--)
if(a[j]!=0)
break;
m=j+1;
for(j=lena-1;j>=0;j--)//判断还能否继续减
if(c[j]!=0)
break;
n=j+1;
if(m<n)
break;
if(m==n)
for(j=m-1;j>=0;j--)
{
if(a[j]>c[j])
break;
else if(a[j]<c[j])
{ok=0;break;}
}
if(!ok)
break;
for(j=0;j<m;j++){
a[j]=a[j]-c[j]+digit;//减法操作
digit=0;
if(a[j]<0){
a[j]+=10;
digit=-1;
} }
v[i-1]++;
}}
else
while(1){ok=1;//减单倍运算
for(j=lena;j>=0;j--)
if(a[j]!=0)
break;
m=j+1;
for(j=lena-1;j>=0;j--)
if(b[j]!=0)
break;
n=j+1;
if(m<n)
break;
if(m==n)
for(j=m-1;j>=0;j--)
{
if(a[j]>b[j])
break;
else if(a[j]<b[j])
{ok=0;break;}
}
if(!ok)
break;
for(j=0;j<m;j++){
a[j]=a[j]-b[j]+digit;
digit=0;
if(a[j]<0){
a[j]+=10;
digit=-1;
} }
v[0]++;
}}
for(i=lena-lenb-1;i>=0;i--)//判断是否有某一位大于10
if(v[i]>=10){
v[i]-=10;
v[i+1]++;
i++;
}
for(p=lena-lenb+1;p>=0;p--)//判断结果的长度
if(v[p]>0)
break;
return p;
}
int main()
{ char c,tempa[10000],tempb[10000];
int a[10000]={0},b[10000]={0},flag;
int i=0,j,lena,lenb,m,fu=0,n,ok;
printf("------------------加减乘除高精度计算器--------------------\n\n");
printf("请输入程序有效计算次数(输入-1代表无限循环):");
scanf("%d",&n);
getchar();
printf("\n");
while(n--){fu=0;i=0;ok=1;
memset(a,0,sizeof(a));//每次循环数组清零
memset(b,0,sizeof(b));
memset(v,0,sizeof(v));
while((c=getchar())!='\n')//输入字符数组a
{if(c!='+'&&c!='-'&&c!='*'&&c!='/'&&(c<'0'||c>'9'))
ok=0;
if(c=='+'||(c=='-'&&i!=0)||c=='*'||c=='/')
break;
else
{tempa[i++]=c;
if(i==1&&c=='-')//当第一个数为负数时
{i--;fu++;}
}
}
if(i==0||c=='\n')//误碰回车时自动重新输入
{n++;continue;}
if(fu>1)//输入两个负号时报错
{printf("输入错误,请重新输入!\n\n");
n++;
continue;
}
flag=c;
lena=i;//数字位数
i=0;
while((c=getchar())!='\n')//输入字符数组b
{if(c<'0'||c>'9')
ok=0;
tempb[i++]=c;
}
if(i==0)//误碰回车时自动重新输入
{n++;continue;}
if(ok==0)//输入其它符号时报错
{printf("输入错误,请重新输入!\n\n");
n++;
continue;
}
lenb=i;
for(i=lena-1,m=0;i>=0;i--)//倒序赋值到整形数组上
a[m++]=tempa[i]-'0';
for(i=lenb-1,m=0;i>=0;i--)
b[m++]=tempb[i]-'0';
printf("Answer:\n");
//针对输入 000 或001 等情况
/*for(j=lena-1;j>=0;j--)
if(a[j]!=0)
break;
lena=j+1;
if(lena==0)
lena++;
for(j=lenb-1;j>=0;j--)
if(a[j]!=0)
break;
lenb=j+1;
if(lenb==0)
lenb++;*/
/*
for(i=0;i<lena;i++)
printf("%d",a[i]);//预留检验输入数组工具
printf("\n");
for(i=0;i<lenb;i++)
printf("%d",b[i]);
printf("\n");
*/
if(flag=='+'&&fu==0)//加法操作
{j=add(a,b,lena,lenb);
for(;j>=0;j--)
printf("%d",v[j]);
printf("\n");}
if(flag=='+'&&fu==1)
{//加法转减法操作
j=mil(b,a,lenb,lena);
for(;j>=0;j--){
if(v[j]==-1)
printf("-");
if(v[j]>=0)
printf("%d",v[j]);
}
printf("\n");
}
if(flag=='-'&&fu==0){//减法操作
j=mil(a,b,lena,lenb);
for(;j>=0;j--){
if(v[j]==-1)
printf("-");
if(v[j]>=0)
printf("%d",v[j]);
}
printf("\n");
}
if(flag=='-'&&fu==1)//减法转加法操作
{j=add(a,b,lena,lenb);
printf("-");
for(;j>=0;j--)
printf("%d",v[j]);
printf("\n");}
if(flag=='*')//乘法操作
{j=mul(a,b,lena,lenb);
if(fu==1&&v[j]!=0)
printf("-");
for(;j>=0;j--)
printf("%d",v[j]);
printf("\n");
}
if(flag=='/')//除法操作
{if(lenb==1&&b[0]==0)
{printf("分母不能为0!\n\n");
continue;
}
j=div(a,b,lena,lenb);
if(fu==1)
printf("-");
if(j==-1)
printf("0");
else
for(;j>=0;j--)
printf("%d",v[j]);
printf(".");
for(i=lena;i>=0;i--)//除法小数点后操作
if(a[i]!=0)
{lena=i+1;break;}
if(lena==0)
printf("000000000");
for(;i>=0;i--)
a[i+9]=a[i];
for(i=0;i<=8;i++)
a[i]=0;
memset(v,0,sizeof(v));
j=div(a,b,lena+9,lenb);
for(j=8;j>=0;j--)
printf("%d",v[j]);
printf("\n");}
printf("\n");
}
system("pause");
return 0;
}