一、簡介
眾所周知,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 }
