大数计算

  1#include <stdio.h> 
  2#include <stdlib.h> 
  3#include <string.h> 
  4#include <ctype.h> 
  5
  6int cchkdig(char *r) 
  7
  8    int i = 0 ;  
  9    while (r[i] != '\0'
 10    
 11        if (isdigit(r[i++]) == 0
 12            return (0); 
 13    }
 
 14    return (1);  
 15}
 
 16
 17//去掉整数串表示前面多余的零,最后结果为空串时置为"0" 
 18void cdel0(char *r) 
 19{
 20    unsigned int lr ;  
 21    int i = 0 ; 
 22    int j ; 
 23    lr = strlen(r);  
 24    while (r[i] == '0'
 25        ++i ;
 26    if (i > 0
 27    {
 28        for(j = 0; j < lr-i; ++j)
 29            r[j] = r[j + i] ;
 30        for(j = lr-i; j < lr; ++j) 
 31        {
 32            r[j] = '\0'
 33        }

 34        
 35    }

 36    
 37    if(r[0== '\0')
 38    {
 39        r[0= '0';
 40    }
 
 41}
 
 42
 43int scmp(char *r, char *u) 
 44
 45    unsigned int lr, lu ; 
 46    cdel0(r) ;
 47    cdel0(u) ; 
 48    
 49    lr = strlen(r) ; 
 50    lu = strlen(u) ; 
 51    
 52    if(lr > lu) 
 53    {
 54        return 1 ;
 55    }

 56    else if (lr < lu) 
 57    {
 58        return -1 ;
 59    }

 60    return (strcmp(r, u)) ; 
 61    
 62}
//end scmp() 
 63
 64//两个串表示数的减法 
 65char *ssub(char *r, char *u) 
 66{
 67    unsigned int i, lr, lu, lp, c=0 ;  
 68    char h, hc ; 
 69    char *p ;
 70    if (scmp(r, u) < 0
 71        return NULL ; 
 72    lr = strlen(r) ; 
 73    lu = strlen(u) ; 
 74    p = (char *)malloc((unsigned int)(lr + 1* sizeof(char)) ; 
 75    for (i = 0; i < lu; ++i) 
 76    {
 77        h = r[lr - i - 1- u[lu - i - 1- c ; 
 78        if (h < 0
 79        {
 80            c = 1 ; 
 81            h = h + 10 ;
 82        }
 
 83        else 
 84            c = 0 ; 
 85        p[i] = h + '0' ;
 86        hc = h + '0' ;
 87    }
 
 88    for (i = lu; i < lr; ++i) 
 89    
 90        h = r[lr - i - 1- '0' - c ;
 91        if (h < 0
 92        {
 93            c = 1 ; 
 94            h = h + 10 ; 
 95        }
 
 96        else 
 97            c = 0 ;  
 98        p[i] = '0' + h ; 
 99        hc = '0' + h ;
100    }

101    p[i] = '\0' ;
102    lp = i - 1 ;
103    
104    while (p[lp] == '0' && lp != 0)
105    {
106        p[lp] = '\0' ;
107        lp-- ; 
108    }

109    
110    
111    for (i = 0; i < (lp + 1/ 2++i) 
112    
113        hc = p[i] ; 
114        p[i] = p[lp - i] ; 
115        p[lp - i] = hc ; 
116    }
 
117    return (p) ; 
118}
//end ssub() 
119
120//两个串表示数的加法 
121char *sadd(char *r, char *u) 
122
123    unsigned int lr, lu, lp; 
124    int i, h, c = 0 ; 
125    char hc, *p ; 
126    lr = strlen(r) ; 
127    lu = strlen(u) ; 
128    if(lu > lr) 
129    
130        p  = r  ; 
131        r  = u  ; 
132        u  = p  ; 
133        h  = lr ; 
134        lr = lu ; 
135        lu = h  ; 
136    }
 
137    p = (char *)malloc((unsigned int)(lr + 2* sizeof(char)) ;  
138    for (i = 0; i < lu; ++i) 
139    
140        h = r[lr - i - 1- '0' + u[lu - i - 1- '0' + c ; 
141        if (h > 9
142        
143            c = 1 ;
144            h = h - 10 ; 
145        }
 
146        else 
147            c = 0 ;  
148        p[i] = h + '0' ;  
149    }
 
150    for (i = lu; i < lr; ++i) 
151    
152        h = r[lr - i - 1- '0' + c ; 
153        if (h > 9
154        
155            c = 1 ; 
156            h = h - 10 ; 
157        }
 
158        else 
159            c = 0 ;  
160        p[i] = '0' + h ;  
161    }
 
162    if (c > 0
163    
164        p[i] = c + '0' ; 
165        lp = i ; 
166    }
 
167    else 
168        lp = i - 1 ;  
169    for (i = lp + 1; i < lr + 2++i) 
170        p[i] = '\0' ; 
171    for (i = 0; i < (lp + 1/ 2++i) 
172    
173        hc = p[i] ; 
174        p[i] = p[lp - i] ;  
175        p[lp - i] = hc ; 
176    }
 
177    return (p) ; 
178}
//end sadd() 
179
180//两个串表示数的乘法 
181char *smut(char *r, char *u) 
182
183    unsigned int lr, lu, lp; 
184    int i, j, c, h; 
185    char *p; 
186    lr = strlen(r) ; 
187    lu = strlen(u) ; 
188    p = (char *)malloc((unsigned int)(lr + lu + 1* sizeof(char)) ; 
189    for (i = 0; i < lr + lu; ++i) 
190        p[i] = '0' ; 
191    p[lr + lu] = '\0' ; 
192    
193    for (i = lr - 1; i >= 0--i) 
194    
195        c = 0 ;  
196        for (j = lu - 1; j >= 0--j) 
197        
198            lp = i + j + 1 ;  
199            h = (r[i] - '0'* (u[j] - '0'+ p[lp] - '0' + c ;  
200            c = h / 10 ;  
201            h = h % 10 ;  
202            p[lp] = h + '0' ;  
203        }
 
204        if (c > 0)p[i + j + 1= c + '0' ;  
205    }
 
206    
207    cdel0(p) ;  
208    return p ;  
209}
//end smut() 
210
211//两个串表示数的除法,结果精确到小数点后第n位 
212char *sdivf(char *u, char *v, int n) 
213
214    char *p, *f, *r, *q ;  
215    unsigned int i, lu, lv, lr,  iw, c, h ;  
216    int  kh, j ;  
217    lu = strlen(u) ;  
218    lv = strlen(v) ;  
219    f = (char *)malloc((unsigned int)(lu + n + 3* sizeof(char)) ; 
220    q = (char *)malloc(sizeof(char)) ; 
221    for (i = 0; i < lu + n + 3++i) 
222        f[i] = '\0' ; 
223    r = (char *)malloc((unsigned int)(lv + 2* sizeof(char)) ; 
224    for (i = 0; i < lv + 2++i) 
225        r[i] = '\0' ; 
226    for (iw = 0; iw < lu + n + 2++iw) 
227    
228        if (iw < lu) 
229        
230            cdel0(r) ; 
231            lr = strlen(r) ; 
232            r[lr] = u[iw] ; 
233            r[lr + 1= '\0' ;
234        }
 
235        
236        else if (iw > lu) 
237        
238            cdel0(r) ;
239            q[0= '0' ;
240            if (scmp(r, q) == 0)
241            {
242                break ; 
243            }

244            lr = strlen(r) ; 
245            r[lr] = '0' ;
246            r[lr + 1= '\0' ; 
247        }
 
248        
249        else 
250        
251            f[lu] = '.' ; 
252            continue ;  
253        }

254        
255        kh = 0 ; 
256        while (scmp(r, v) >= 0
257        
258            p = r ;
259            r = ssub(p, v) ; 
260            ++kh ; 
261        }
 
262        f[iw] = kh + '0' ; 
263    }
 
264    if (iw == lu + n + 2
265    
266        if (f[lu + n + 1>= '5'
267        
268            f[lu + n + 1= '\0' ;  
269            c = 1 ;  
270            for (j = lu + n; j >= 0--j) 
271            
272                if (c == 0
273                {
274                    break ;  
275                }

276                if (f[j] == '.')
277                {
278                    continue ; 
279                }

280                h = f[j] - '0' + c ;  
281                if (h > 9
282                
283                    h = h - 10 ; 
284                    c = 1 ; 
285                }
 
286                else 
287                    c = '\0' ;  
288                f[j] = h + '0' ; 
289            }
 
290        }
 
291        else 
292            f[lu + n + 1= '\0' ; 
293        
294    }
 
295    free(r) ; 
296    free(p) ;
297    q = NULL ;
298    free(q) ;
299    cdel0(f) ;  
300    return(f) ;  
301}
//end sdivf() 
302
303//两个串表示数的除法,结果分别用整商与余数表示 
304char *sdivkr(char *u, char *v, char **rout) 
305
306    char  *f, *r ;  
307    unsigned int i, lu, lv, lr, iw ;  
308    int  kh ;  
309    lu = strlen(u) ;  
310    lv = strlen(v) ;  
311    
312    f = (char *)malloc((unsigned int)(lu + 1* sizeof(char)) ; 
313    for (i = 0; i < lu+1++i) 
314        f[i] = '\0' ; 
315    r = (char *)malloc((unsigned int)(lv + 2* sizeof(char)) ; 
316    for (i = 0; i < lv + 2++i) 
317        r[i] = '\0' ; 
318    
319    for (iw = 0; iw < lu; ++iw) 
320    
321        cdel0(r) ; 
322        lr = strlen(r) ; 
323        r[lr] = u[iw] ; 
324        r[lr + 1= '\0' ; 
325        kh = 0 ; 
326        while (scmp(r, v) >= 0
327        
328            r = ssub(r, v) ; 
329            ++kh ; 
330        }
 
331        f[iw] = kh + '0' ; 
332    }
 
333    cdel0(r) ;  
334    *rout = r ;  
335    cdel0(f) ; 
336    return(f) ;
337    
338}
//end *sdivkr() 
339
340//调用上述函数实现两任意长正整数任意指定精度的算术计算器程序 
341int main(int argc, char *argv[]) 
342
343    char *p, *r ;  
344    int n ;  
345    if (argc != 4)
346    
347        if (argc != 3)
348            printf("\n>>\"order n1 op n2\" or n ! ") ; 
349        exit(0) ; 
350    }
 
351    cdel0(argv[1]);  
352    if (cchkdig(argv[1]) == 0)
353    
354        printf("Input data error, Input again!") ; 
355        exit(0) ; 
356    }
 
357    cdel0(argv[3]) ;  
358    if (cchkdig(argv[3]) == 0
359    
360        printf("Input data error, Input again!") ; 
361        exit(0) ; 
362    }
 
363    
364    if (strcmp(argv[2], "+"== 0
365    
366        printf("%s", p = sadd(argv[1], argv[3])) ; 
367        free(p) ; 
368    }
 
369    
370    else if (strcmp(argv[2], "-"== 0
371    
372        printf("%s", p = ssub(argv[1], argv[3])) ; 
373        free(p) ; 
374    }
 
375    
376    else if(strcmp(argv[2], "*"== 0
377    
378        printf("%s", p=smut(argv[1], argv[3])) ; 
379        free(p) ; 
380    }
 
381    
382    else if(argv[2][0== '/' && strlen(argv[2]) == 1
383    
384        if (argv[3][0== '0')
385        {
386            printf("error!devided by zero!!\n") ;
387            exit(0) ;
388        }

389        p = sdivkr(argv[1], argv[3], &r) ;  
390        printf("k = %s r = %s", p, r) ;  
391        free(p) ; 
392        free(r) ;  
393    }
 
394    
395    else if (argv[2][0== '/' && strlen(argv[2]) > 1
396    
397        if (argv[3][0== '0')
398        {
399            printf("error!devided by zero!!\n") ;
400            exit(0) ;
401        }

402        
403        argv[2][0= '\0' ;  
404        cdel0(argv[2]) ;  
405        if (cchkdig(argv[2]) == 0
406        
407            printf("Input data error, Input again!") ; 
408            exit (0) ; 
409        }
 
410        n = atoi(argv[2]) ;  
411        printf("%s", p = sdivf(argv[1], argv[3], n)) ;
412        free(p) ;  
413    }
 
414    
415    return 0 ;
416}
 
posted @ 2007-04-15 20:54  Edward Xie  阅读(196)  评论(0)    收藏  举报