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]!='\0'){
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 }

 

posted @ 2018-01-19 19:05  鱼儿游上天  阅读(8897)  评论(0编辑  收藏  举报