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 }