c语言版大数计算器(实现大数的加减乘除运算,已更新源代码)

一、         实验环境

 VC6.0

 

二、         实验目的

实现大整数(100位整数)的加减乘除运算。

三、         实验内容

1.      用C语言实现串的存储结构——顺序串 ;

2.    利用串解决实际应用问题(实现大整数计算器)。实现串的基本操作(求串长、复制串、串比较、串连接、插入串、删除串)及模式匹配算法:BF(BruteForce)算法或KMP(Knuth、Morris、Pratt)算法的相关函数子程序。

3.    利用串解决实际应用问题(实现大整数计算器)。

 

四.       数据结构与算法思想描述

由于整型数的位数有限,因此整型数不能满足大整数(超长整数)的运算要求 。大整数计算器是利用字符串来表示大整数,即用字符串的一位字符表示大整数的一位数值,然后根据四则运算规则实现大整数的四则运算。

具体思想步骤如下:

(1)   循环主菜单,菜单选项包括输入两个操作数,加减乘除运算,退出计算器。

(2)加法:从最低位(即字符串的最后一个字符)开始逐位相加,若结果未达到或超过10,则相加结果即为本位计算结果;否则,产生进位1预存计入上一位;将该位计算结果存入另一个字符型数组的相应位中(即将计算结果存入另一字符型数组中);直至加完大整数所有位为止。

 

(3)减法:首先判断被减数和减数哪个大(做长度判断),从而可决定结果为正数还是负数。然后用长的减去短的,还是从最低位开始逐位相减,不够减时则向上一位借位(即进位为-1),同时将该位计算结果存入另一个字符型数组的相应位中,直至求出每一位的结果

 

(4)乘法:相当于做若干次加法。被乘数自己加自己共做(乘数-1)次加法(即每做一次加法乘数减1,直到乘数减为1时为止)。

 

(5)除法:相当于做若干次减法。从被除数里不断减去除数,直到被除数减到小于除数时(不够减时)为止,已做减法的次数即为商,减后的剩余部分(不够减的部分)即为余数。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct node{
   char s[1000];
   int len;

}sstring;
void init(sstring *a,char *data){//将字符串赋值到串里。
   int i,j;
   j=strlen(data);
   for(i=0;i<j;i++){
       a->s[i]=0;
        a->s[i]=data[i];
   }
   a->s[i]='\0';
   a->len=j;

}
int com(sstring *a1,sstring *b1){//比较两数的大小。
    if(a1->len>b1->len){ return 1;}
    else if(a1->len==b1->len) {
       int i=0;
       while(a1->s[i]==b1->s[i]&&i<a1->len){
            i++;
       }
       if(i==a1->len) return 0;
       else if(a1->s[i]>b1->s[i]) return 1;
       else return -1;
    }
    else return -1;

}
void add(sstring *a1,sstring *b1,sstring *c1){
    char pp[100];
    int a[100];//加数
    int b[100];//被加数
    int c[100]={0};//和
    int i,j=0,k;//i用来循环,j表示进位 ,两加数中较小加数的长度放到k里
    int l1,l2,d;
    l1=a1->len;
    l2=b1->len;
    k=l1>l2?l2:l1;
    for(i=0;i<a1->len;i++){//字符串逆序导入数组中
         a[i]=a1->s[l1-1-i]-'0';
    }
    for(i=0;i<b1->len;i++){
         b[i]=b1->s[l2-1-i]-'0';
    }
    for(i=0;i<k;i++){
       d=a[i]+b[i]+j;
       j=d/10;
       c[i]=d%10;
    }
    while(i<l1){
        d=a[i]+j;
        j=d/10;
        c[i]=d%10;
        i++;
    }
     while(i<l2){
        d=b[i]+j;
        j=d/10;
        c[i]=d%10;
        i++;
    }
   if(j>0){c[i]=j;i++;}
   for(j=0,k=i-1;k>-1;k--,j++)
    pp[j]=c[k]+'0';
    pp[j]='\0';
   init(c1,pp);

}
void subtract(sstring *a1,sstring *b1,sstring *c1){
    int a[100];//把较大的数放于减数
    int b[100];//把较小的数放于被减数
    int c[100]={0};//差
    int i,j,k;//i用来循环 ,两加数中较大加数的长度放到j里,两加数中较小加数的长度放到k里
    int flag;//标志结果为正还是负。
    int l1,l2;
    char pp[100];
    l1=a1->len;
    l2=b1->len;
    k=l1>l2?l2:l1;
    j=l1<l2?l2:l1;
    if(strcmp(a1->s,b1->s)==0){
        init(c1,"0");
    }
    else{
        if(com(a1,b1)>=0){//减数必须大于被减数。方便计算。如果小于,就调换位置。
            flag=0;
            for(i=0;i<l1;i++){//字符串逆序导入数组中
               a[i]=a1->s[l1-1-i]-'0';
            }
             for(i=0;i<l2;i++){
               b[i]=b1->s[l2-1-i]-'0';
            }
        }
        else{
             flag=1;
             for(i=0;i<l2;i++){
               a[i]=b1->s[l2-1-i]-'0';
            }
             for(i=0;i<l1;i++){
               b[i]=a1->s[l1-1-i]-'0';
            }
        }
        for(i=0;i<k;i++){
           if(a[i]>=b[i]) c[i]=a[i]-b[i];
              else{
              c[i]=a[i]+10-b[i];
              --a[i+1];
           }

         }

    while(i<j){
           if(a[i]>=0) c[i]=a[i];
           else{
               c[i]=a[i]+10;
              --a[i+1];
           }
          i++;
        }
        while(c[i-1]==0) i--;
         j=0;
        if(flag==1)
           pp[j++]='-';
        for(k=i-1;k>-1;k--,j++)
            pp[j]=c[k]+'0';
        pp[j]='\0';
       init(c1,pp);
    }

}
void multiply(sstring *a1,sstring *b1,sstring *c1){

    int a[100];
    int b[100];
    int c[100]={0};
    int d,i,j,k;//i,j用来循环
    int flag=0;//进位
    int l1,l2;
    l1=a1->len;
    l2=b1->len;
     init(c1,"0");
    for(i=0;i<a1->len;i++){
         a[i]=a1->s[l1-1-i]-'0';
    }
    for(i=0;i<b1->len;i++){
         b[i]=b1->s[l2-1-i]-'0';
    }
    for(i=0;i<l2;i++){
        flag=0;
        for(j=0;j<l1;j++){
            d=a[j]*b[i]+flag;
            c[j]=d%10;
            flag=d/10;
        }
        if(flag>0){
            c[j]=flag;
            j++;
        }
        while(c[j-1]==0)j--;
    
        char str[100];
        for(k=0;k<j;k++)
            str[k]=c[j-1-k]+'0';
        for(j=0;j<i;j++)str[k++]='0';
        str[k]='\0';
        sstring *ff;
        ff=(node *)malloc(sizeof(node));
        init(ff,str);
        add(c1,ff,c1);
    }

}
void one(char *a){
   int i,l=strlen(a);
   int carry=1; 
   char t;
   for(i=0;i<l;i++){
     t=a[i]+carry;
     if(t>9+'0'){
         t='0';
         carry=1;
     }
     else{
         carry=0;
     }
     a[i]=t;
   }
   if(carry==1)a[i++]='1';
   a[i]='\0';
}
void divide(sstring *a1,sstring *b1,sstring *c1,sstring *d1){//C为商,D为余数
  // int i,j,k,
    char t[100]={0};
   char b[2]="0";
   if(com(a1,b1)==0){
        init(d1,"0");
        init(c1,"1");
   }
   else if(com(a1,b1)<0){
         init(d1,a1->s );
        init(c1,"0");
   }
   else{
    sstring *aa;
    aa=(node *)malloc(sizeof(node));
    init(aa,a1->s);
   while(com(aa,b1)>=0){
        subtract(aa,b1,c1);
        init(aa,c1->s);
        one(t);
   } 
    init(c1,t);
    init(d1,aa->s);
   }
}
int main(){
   int flag=1;
   while(flag){
     printf("\n--------------------------------大整数计算器----------------------------------\n");
     printf("\n *************** 0,退出       1,输入两个操作数       2,两数相加 ************* \n");
     printf("\n *************** 3,两数相减   4,两数相乘            5,两数相除*************\n");
        printf("\n 提示:按相应数字进行相应操作,请先输入操作数再进行运算 \n");
     printf("\n----------------------------------------------------------------------------\n");
     scanf("%d",&flag);
     sstring  *a,*b,*c;
     a=(node *)malloc(sizeof(node));
     b=(node *)malloc(sizeof(node));
     c=(node *)malloc(sizeof(node));
     if(flag==1){
       printf("\n 请输入操作数: \n");
           char a1[100],b1[100];
           scanf("%s",&a1);
           scanf("%s",&b1);
           init(a,a1);
           init(b,b1);
           int co;
           printf("\n 请输入运算操作: \n");
           scanf("%d",&co);
           while(co){
               if(co==1){
                   printf("\n 请重新输入操作数 !!\n");
                    break;
               }
               else if(co==2){
                   add(a,b,c);
                   printf("两者之和为:%s\n",c->s);
               }
               else if(co==3){
                 subtract(a,b,c);
                printf("两者之差为:%s\n",c->s);
                }
                else if(co==4){ 
                    multiply(a,b,c);
                     printf("两者之积为:%s\n",c->s);
                }
                else if(co==5){
                    sstring  *d;
                    d=(node *)malloc(sizeof(node));
                    if(strcmp(b->s,"0")==0)
                    { printf("除数不能为0");break;}
                    else{
                     divide(a,b,c,d);
                      printf("商为:  ") ;
                     int i=strlen(c->s)-1;
                     for(;i>=0;i--){
                           printf("%c",c->s[i]);
                     }
                    printf(" 余数为:%s ",d->s);
                    }
                    
                }
                else {
                       printf("\n 输入错误,请重新输入!!!\n");
                        
                    }
            printf("\n 请输入运算操作: \n");
            scanf("%d",&co);
           }
        }
     else if(flag==0){
          printf("\n 退出该计算器。 \n");
     }
     else{

         printf("\n 输入错误,请重新输入!!!\n");

     }



   }
  return 0;

}

结果图:

《c语言版大数计算器(实现大数的加减乘除运算,已更新源代码)》

《c语言版大数计算器(实现大数的加减乘除运算,已更新源代码)》

这个东东呢,希望和大家一起探讨。大数的乘除法运用的是比较笨拙的方法。如果你们有比较好的方法可以介绍给我吗?

           ~~~~加油~~~~~

    原文作者:大整数乘法问题
    原文地址: https://blog.csdn.net/Pabebe/article/details/53741606
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞