⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 calculate(sign).c

📁 该程序用C语言实现了大整数的加减乘除运算
💻 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 + -