📄 calculate(sign).c
字号:
#define N 25 /*通过修改N可改变运算位数,4N*/
#include<stdio.h>
void print(long c[],int flag) /*打印带符号flag(1为负)的long c[]数组*/
{
int i;
for(i=N-1;i>=0;i--) /*得到数组最高不为0位*/
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数组接收键盘敲入数字,由于long数组四位一组,故长4N*/
char temp;
int i,j,k;
for(i=0;i<N*4;i++){ /*从字符数组最低位开始储存*/
num[i]=getchar();
if(num[i]==10){ /*若为回车则跳出,且i自减,避开储存的回车位*/
i--;
break;
}
if(num[i]==45){
flag=(flag+1)%2; /*若为'-'亦跳出,改变正负,i自减,避开储存的'-'*/
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++) /*将字符数组四个一位放入long a[]数组,根据位数做相应调整*/
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 add(long a[],long b[],long c[]) /*对a b进行加法运算,结果放在c*/
{
int max_i;
int max_j;
int max; /*max_i,max_j,max分别记录b a最高位和两者最大值*/
int i;
int temp;
for(max_i=N-1;max_i>=0;max_i--) /*获得b最高位*/
if(b[max_i])
break;
for(max_j=N-1;max_j>=0;max_j--) /*获得a最高位*/
if(a[max_j])
break;
if(max_i>max_j) /*得到两者最大值,用来判断加法应该进行到的位数*/
max=max_i;
else max=max_j;
for(i=0;i<=max;i++){ /*从最低位加到两者的最高位*/
temp=a[i]+b[i];
c[i]=c[i]+temp%10000; /*c[i]等于前面的进位加上a[i]与b[i]的和的低4位*/
c[i+1]=c[i]/10000+temp/10000; /*进位可能由a+b,或c[i]加了低四位后造成*/
c[i]=c[i]%10000; /*c[i]加上a+b低四位后可能有进位*/
}
}
/***************************************/
void mul(long a[],int first,int last,long b[],long c[]) /*乘法,a的第last到first位乘以b,答案放到c*/
{
int i,j;
int max_i;
long temp;
for(max_i=N-1;max_i>=0;max_i--) /*得到b的最高位*/
if(b[max_i])
break;
for(i=0;i<=max_i;i++) /*b从最低位循环到最高位*/
if(b[i]) /*b为零不进行运算处理*/
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大小,first last分别为a的最高最低位*/
{
int flag=2; /*记录比较结果,相同为2,a>b为1,小于为0*/
int i;
int k=0;
int len; /*记录b的最高位*/
for(len=N-1;len>=0;len--) /*获得b最高位*/
if(b[len])
break;
if((first-last)>=len){
if((first-last)>len) flag=1;/*如果a位数多于b,a>b*/
else
for(i=len;i>=0;i--){ /*如果长度相等而某一位a>b,则a>b*/
if(a[first-k]>b[i]){
flag=1;
break;
}
if(a[first-k]<b[i]){ /*如果长度相等而某一位a<b,则a<b*/
flag=0;
break;
}
k++;
}
}
else flag=0;/*如果b位数大于a,则a>b*/
return flag;/*返回比较结果*/
}
/***************************************/
int minus(long a[],int first,int last,long b[],long c[],int flag)
/*a为被减数,first last为a最高最低位,b为减数,c为差,flag为符号*/
{
int notchange;/*记录是否需要调换被减数与减数*/
int i,k=0;
int max; /*记录b最高位*/
notchange=compara(a,first,last,b); /*如果a大于b*/
if(notchange){ /*a大于b不用交换*/
for(i=last;i<=first;i++){ /*从地位循环到高位*/
if(a[i]<b[k]){ /*若某位a小于b,需要向高位借位*/
a[i]+=10000;
a[i+1]--;
}
c[i]=a[i]-b[k]; /*记录差*/
k++;
}
}
else{
flag=(flag+1)%2; /*如果b比a大,调换被减数与减数,改变符号*/
for(max=N-1;max>=0;max--)/*得到b最高位*/
if(b[max])
break;
for(i=0;i<=max;i++){ /*算法与a-b一样*/
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) /*除法,a除以b的值放入c,fa为a符号*/
{
long result[N+1]={0}; /*记录运算过程中某位与b的乘积*/
int len_a,len_b; /*记录a b的最大不为0位*/
int k;
int i;
printf("\n");
print(a,fa); /*由于a在计算过程中会改变,最后变成余数,所以先打印作为被除数*/
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值直到a的最高非零位到k位的值比除数大*/
k--;
c[k]=1;
mul(c,k,k,b,result); /*k位就是参与运算的被除数最低位,正好是要求的商的位数*/
while(compara(a,len_a,k,result)){ /*该位商自增乘以除数直到比被除数参加运算部分大*/
c[k]++;
for(i=N-1;i>=0;i--) /*每次运算结果放在result数组中,每次都必须清零*/
result[i]=0;
mul(c,k,k,b,result);
}
c[k]--; /*当除数与该位成绩正好大于被除数位段时,该位减1就是该位的商*/
for(i=N-1;i>=0;i--) /*将result清零*/
result[i]=0;
mul(c,k,k,b,result); /*该位商乘以除数*/
minus(a,len_a,k,result,a,0); /*a参加运算位段减去result*/
for(i=N-1;i>=0;i--) /*result清零*/
result[i]=0;
for(len_a=N-1;len_a>=0;len_a--) /*得到现在a的最高不为0位*/
if(a[len_a])
break;
k=len_a; /*k指向最高位*/
}
}
/***************************************/
main()
{
int flag; /*记录最后答案的符号*/
int max; /*记录最高位*/
int fa; /*记录a数组符号*/
int fb; /*记录b数组符号*/
long a[N];
long b[N];
long c[2*N];
int choose=1; /*菜单选择*/
while(choose){
flag=fa=fb=0; /*每次循环必须将数组符号清零,否则会出错*/
for(max=0;max<N;max++)
a[max]=b[max]=c[max]=0;
printf("\nThe program is used for calculate in large numbers,choose the kind of calculate you want:\n1 add\n2 minus\n3 multiply\n4 division\n0 exit");
scanf("%d",&choose);
getchar(); /*接受多于的回车*/
switch(choose)
{
case 1: printf("\nPlease input an addend:(Shorter than 100,Press ENTER to end)");
fa=write(a,fa);
printf("\nPlease input another addend:(Shorter than 100,Press ENTER to end)");
fb=write(b,fb);
for(max=N-1;max>=0;max--)
if(a[max])
break;
if(fa&&fb) { /*如果a b均为负,符号为负,进行正数加*/
flag=1;
add(a,b,c);
}
if(fa==0&&fb==0) /*如果a b均为正,直接进行加法运算*/
add(a,b,c);
if(fa==0&&fb) /*如果a为正b为负,执行a-b*/
flag=minus(a,max,0,b,c,flag);
if(fa&&fb==0){ /*如果a为负,b为正,执行-(a-b)*/
flag=1;
flag=minus(a,max,0,b,c,flag);
}
printf("\n"); /*打印结果*/
print(a,fa);
printf(" + ");
print(b,fb);
printf(" = ");
print(c,flag);
break;
case 2: printf("\nPlease input the minuend:(Shorter than 100,Press ENTER to end)");
fa=write(a,fa);
printf("\nPlease input the subtrahead:(Shorter than 100,Press ENTER to end)");
fb=write(b,fb);
for(max=N-1;max>=0;max--)
if(a[max])
break;
if(fa&&fb){ /*-a-(-b)=b-a=-(a-b)*/
flag=1;
flag=minus(a,max,0,b,c,flag);
}
if(!fa&&!fb) /*均为正直接执行减法运算*/
flag=minus(a,max,0,b,c,flag);
if(fa==0&&fb) /*a-(-b)=a+b*/
add(a,b,c);
if(fa&&fb==0){ /*-a-b=-(a+b)*/
flag=1;
add(a,b,c);
}
printf("\n"); /*打印结果*/
print(a,fa);
printf(" - ");
print(b,fb);
printf(" = ");
print(c,flag);
break;
case 3: printf("\nPlease input a mutiplier:(Shorter than 100,Press ENTER to end)");
fa=write(a,fa);
printf("\nPlease input another multiplier:(Shorter than 100,Press ENTER to end)");
fb=write(b,fb);
flag=(fa+fb)%2;
for(max=N-1;max>=0;max--) /*得到a最高位*/
if(a[max])
break;
mul(a,0,max,b,c); /*进行乘法运算*/
printf("\n"); /*打印结果*/
print(a,fa);
printf(" * ");
print(b,fb);
printf(" = ");
print(c,flag);
break;
case 4: printf("\nPlease input the dividend:(Shorter than 200,Press ENTER to end)");
fa=write(c,fa);
printf("\nPlease input the divisor:(Shorter than 100,Press ENTER to end)");
fb=write(b,fb);
div(c,b,a,fa); /*调用除法运算*/
flag=(fa+fb)%2; /*打印结果*/
printf(" / ");
print(b,fb);
printf(" = ");
print(a,flag);
printf("(");
print(c,0);
printf(")");
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -