• C语言实现大数四则运算


    一、简介

    众所周知,C语言中INT类型是有限制,不能进行超过其范围的运算,而如果采用float类型进行运算,由于float在内存中特殊的存储形式,又失去了计算的进度。要解决整个问题,一种解决方法是通过字符串数组实现数据的存储,然后实现它们之间四则运算的函数。

    二、数据结构

    为了实现字符数组之间的运算,要考虑数值的正负性,数字的长度以及具体存储的数字

    typedef struct num{
        int len;   //数值长度 
        char symbol; //数字正负形 
        int number[LEN]; //数组 
    }NUM,*SNUM;

    三、函数

     整个程序使用了一下的函数

    SNUM expToNum(char exp[]);//将输入字符串转换为对应结构体 
    void reverse(int a[],int len);//数组逆序
    int compareAbs(SNUM left,SNUM right);//比较两数绝对值大小 
    SNUM anti_add(SNUM left,SNUM right);//元加法
    SNUM anti_sub(SNUM left,SNUM right);//元减法 
    SNUM add(SNUM left,SNUM right);  //加法 
    SNUM sub(SNUM left,SNUM right);  //减法
    SNUM multiply(SNUM left,SNUM right); //乘法 
    SNUM divide(SNUM left,SNUM right); //除法 
    SNUM mod(SNUM left,SNUM right);//求摸运算 

    函数的定义

      1 SNUM multiply(SNUM left,SNUM right){
      2     //left作为被乘数,right作为乘数
      3     SNUM mul = (struct num*)malloc(sizeof(struct num));
      4     int i,j;
      5     for(i=0;i<LEN;i++){
      6         mul->number[i]=0;
      7     }    
      8     
      9     if(left->symbol==right->symbol){
     10         mul->symbol='+';
     11     }else{
     12         mul->symbol='-';
     13     }
     14     
     15 
     16     
     17     for(i=0;i<right->len;i++){
     18         for(j=0;j<left->len;j++){
     19             mul->number[i+j]+=left->number[j]*right->number[i];
     20         }
     21     } 
     22 
     23 
     24     
     25 //    //进位化简 
     26      int len = left->len+right->len-1; //长度
     27 
     28 //     
     29      for(i=0;i<len;i++){
     30             mul->number[i+1]+=mul->number[i]/10;
     31             mul->number[i]%=10;
     32             
     33             if(i==len-1){
     34                 if(mul->number[i+1]!=0){ //还存在高位 
     35                     len++;
     36                 }else{ //进位完毕,退出 
     37                     break;
     38                 }
     39             }
     40      } 
     41      
     42 
     43      
     44 //     //舍去多余0位
     45     for(i=len-1;i>=0;i--){
     46          if(mul->number[i]==0){
     47              len--;
     48          }else{
     49              break;
     50          }
     51      } 
     52      if(len==0){
     53          len=1;
     54      }
     55      
     56      mul->len=len;
     57      
     58     free(left);
     59     free(right);
     60     return mul;
     61 }
     62 
     63  
     64 
     65 //减一个数等于加上一个数的相反数 
     66 SNUM sub(SNUM left,SNUM right){
     67     right->symbol=(right->symbol=='+'?'-':'+');
     68     return add(left,right); 
     69 }
     70 
     71 //比较两数绝对值大小 
     72 int compareAbs(SNUM left,SNUM right){
     73     if(left->len>right->len){   //left的位数更多 
     74         return 1;
     75     }else if(left->len<right->len){ //right的位数更多 
     76         return -1;
     77     }else{
     78         int i=left->len-1;
     79         while(i>=0){   //从高位开始比较 
     80             if(left->number[i]>right->number[i]){
     81                 return 1;
     82             }
     83             if(left->number[i]<right->number[i]){
     84                 return -1;
     85             }
     86             i--;
     87         } 
     88         return 0; //两者绝对值相等 
     89     }
     90 }
     91 
     92 
     93 SNUM expToNum(char exp[]){
     94     
     95     SNUM temp=(struct num*)malloc(sizeof(struct num));
     96     
     97     int locan=0;
     98     //确定正负号 
     99     if(exp[0]=='+'||exp[0]=='-'){
    100           temp->symbol=exp[0];
    101           locan++;
    102     }else{
    103           temp->symbol='+';
    104     }
    105     
    106     //输入到数组 
    107     int count=0;
    108     while(exp[locan]!=''){
    109         temp->number[count]=exp[locan]-'0';
    110         locan++;
    111         count++;
    112     }
    113     
    114     int i=count;
    115     for(i=count;i<LEN-1;i++){
    116         temp->number[i]=0;
    117     }
    118     
    119     temp->len=count;
    120     
    121     
    122     //数组逆序从个位开始计算 
    123     reverse(temp->number,temp->len);
    124     
    125     return temp;
    126 }
    127 
    128 //数组逆序 
    129 void reverse(int a[],int len){
    130     int i,temp;
    131     for(i=0;i<len/2;i++){
    132         temp = a[i];
    133         a[i] = a[len-1-i];
    134         a[len-1-i] = temp;
    135     }
    136 }
    137 
    138 
    139 
    140 //元加法,假设left和right都为正数或0 
    141 SNUM anti_add(SNUM left,SNUM right){
    142     int i=0;
    143 
    144     while(i<left->len||i<right->len){
    145         int sum=0;
    146         sum=left->number[i]+right->number[i];
    147         if(sum>=10){
    148             left->number[i]=sum%10;
    149             left->number[i+1]+=sum/10;   //进位 
    150         }else{
    151             left->number[i]=sum;   //不进位 
    152         }
    153     
    154         i++;
    155     }
    156     
    157     if(left->number[i]!=0){
    158         i+=1;
    159     }
    160     
    161     left->len=i;
    162     return left;
    163 }
    164 
    165 //实现正数或负数的加法 
    166 SNUM add(SNUM left,SNUM right){
    167     SNUM temp;
    168     if(left->symbol==right->symbol){
    169         temp = anti_add(left,right);
    170     }else{
    171         if(compareAbs(left,right)>=0){         
    172                temp = anti_sub(left,right);
    173                         
    174         }else{
    175              temp = anti_sub(right,left);
    176         }
    177     }
    178     return temp;
    179 }
    180 
    181 //元减法,假设left>=right,left和right均为正数或0 
    182 SNUM anti_sub(SNUM left,SNUM right){
    183      int i=0;
    184      int count=0;
    185      while(i<left->len){
    186          int temp = left->number[i]-right->number[i];
    187          if(temp<0){
    188               left->number[i+1]-=1;
    189               left->number[i]=temp+10; //退位 
    190          }else{
    191               left->number[i]=temp;
    192          }
    193               
    194              count+=1;
    195          
    196          i++;
    197      }
    198      
    199     
    200      
    201      
    202      //舍掉多余的0
    203      for(i=count-1;i>=0;i--){
    204          if(left->number[i]==0){
    205              count--;
    206          }else{
    207              break;
    208          }
    209      } 
    210      
    211      if(count==0){
    212          count++;
    213      }
    214      
    215      left->len=count;
    216      return left;
    217      
    218 }
  • 相关阅读:
    CDQ分治
    2-sat
    整体二分
    apache性能优化
    apache反向代理出现502调整
    hadoop学习笔记肆--元数据管理机制
    ssh 免密码登录配置,及其原理
    extjs 中的一些鲜为人知的属性(深渊巨坑)
    hadoop学习笔记叁--简单应用
    hadoop学习笔记贰 --HDFS及YARN的启动
  • 原文地址:https://www.cnblogs.com/cxyc/p/8283676.html
Copyright © 2020-2023  润新知