大数相乘
makefile:
1 mytest:test.o multiply.o
2 gcc $^ -o $@
3 test.o:test.c
4 gcc -I include -c $^ -o $@
5 multiply.o:multiply.c
6 gcc -I include -c $^ -o $@
7
8 clean:
9 rm test.o multiply.o mytest
include/multiply.h:
//File : multiply.h
1 #ifndef __Jerry_Mul__
2 #define __Jerry_Mul
3
4 extern int multiply (unsigned char const *mulcand, unsigned char const *multer, unsigned char *result);
5
6 #endif
test.c:
//File : test.c
1 #include <stdio.h>
2 #include <multiply.h>
3 #include <string.h>
4
5 int main(int argc, char *argv[])
6 {
7 int len_mulcand = strlen(argv[1]);
8 int len_multiler = strlen(argv[2]);
9 int len_result = len_mulcand + len_multiler;
10
11 char *mulcand = malloc (len_mulcand + 1);
12 char *multiler = malloc (len_multiler + 1);
13 char *result = malloc (len_result + 1);
14 strcpy (mulcand, argv[1]);
15 strcpy (multiler, argv[2]);
16
17
18 multiply(mulcand,multiler,result);
19
20 printf("\n");
21 printf("%s x %s = %s\n", mulcand, multiler, result);
22 printf("\n");
23
24
25 free(mulcand);
26 free(multiler);
27 free(result);
28 return 0;
29 }
multiply.c
//File : multiply.c
1 #include <string.h>
2 #include <stdlib.h>
3 #include <multiply.h>
4
5 static unsigned char * Multiplicand, *Multiplicand_end;
6 static unsigned int len_mulcand;
7
8
9 static unsigned char * Multiplier, *Multiplier_end;
10 static unsigned int len_multer;
11
12
13 static unsigned char *AllResult, *AllResult_end;
14 static unsigned char len_result;
15
16
17 static unsigned char * AddonceResult, *AddonceResult_end;
18 static unsigned int len_addonceresult;
19
20 typedef enum errflag
21 {
22 err_None = 0,
23 err_Multiplier = 1,
24 err_Multiplicand = 2,
25 err_AllResult = 4,
26 err_AddonceResult = 8
27 }errflag;
28
29
30 static errflag initmulcand (unsigned char const *mulcand);
31 static errflag initmulter (unsigned char const *multer);
32 static errflag initaddonce(void);
33 static errflag initresult (void);
34 static void initall(unsigned char const *mulcand, unsigned char const *multer);
35 static void add ( unsigned char *back_end_pos);
36 static void onebytemultiply(unsigned char onebyte);
37 static void storeresult(unsigned char *result);
38 static void multiplyall(void );
39 static void multiplyfree(void);
40
41 int multiply (unsigned char const *mulcand, unsigned char const *multer, unsigned char *result)
42 {
43 initall(mulcand,multer);
44 multiplyall();
45 storeresult(result);
46 multiplyfree();
47 }
48
49 void initall(unsigned char const *mulcand, unsigned char const *multer)
50 {
51 errflag flag = err_None;
52 flag |= initmulcand (mulcand);
53 flag |= initmulter (multer);
54 flag |= initaddonce();
55 flag |= initresult();
56
57 if(flag == err_None)
58 return;
59 if(flag & err_AllResult)
60 goto err_1;
61 if(flag & err_AddonceResult)
62 goto err_2;
63 if(flag & err_Multiplier)
64 goto err_3;
65 if(flag & err_Multiplicand)
66 goto err_4;
67 return;
68 err_1:
69 free(AllResult);
70 err_2:
71 free(AddonceResult);
72 err_3:
73 free(Multiplier);
74 err_4:
75 free(Multiplicand);
76 exit(1);
77 }
78
79 void multiplyall( )
80 {
81 unsigned char const * multiplier_pos = Multiplier_end;
82 unsigned char *allresult_pos = AllResult_end;
83 while(multiplier_pos >= Multiplier)
84 {
85 onebytemultiply(*multiplier_pos);
86 add (allresult_pos);
87 multiplier_pos--;
88 allresult_pos--;
89 }
90 }
91
92
93 void storeresult(unsigned char *result )
94 {
95 unsigned char *pos_start = AllResult;
96 while((!(*pos_start)) && (pos_start <= AllResult_end))
97 pos_start++;
98
99 while(pos_start <= AllResult_end)
100 *result++ = (*pos_start++) + '0';
101 *result = '\0';
102
103 }
104
105 void multiplyfree( )
106 {
107 free(AllResult);
108 free(AddonceResult);
109 free(Multiplier);
110 free(Multiplicand);
111 }
112
113 void onebytemultiply(unsigned char onebyte)
114 {
115 unsigned char const *multiplicand_pos = Multiplicand_end;
116 unsigned char *addonceresult_pos = AddonceResult_end;
117 unsigned char temp = 0;
118 while(addonceresult_pos > AddonceResult)
119 {
120 temp = temp + + (*multiplicand_pos) * onebyte;
121 *addonceresult_pos = temp % 10;
122 temp = temp / 10;
123
124 addonceresult_pos--;
125 multiplicand_pos--;
126 }
127 *addonceresult_pos = temp;
128 }
129
130 void add ( unsigned char *back_end_pos)
131 {
132 unsigned char *forward_end_pos = back_end_pos - len_addonceresult;
133 unsigned char *summand_pos = AddonceResult_end;
134 unsigned char *addend_pos = back_end_pos;
135 unsigned char temp = 0;
136
137 while(addend_pos > forward_end_pos)
138 {
139 temp = temp + *summand_pos + *addend_pos;
140 *addend_pos = temp % 10;
141 temp = temp / 10;
142
143 summand_pos--;
144 addend_pos--;
145 }
146 *addend_pos = temp;
147 }
148
149 errflag initmulcand (unsigned char const *mulcand)
150 {
151 unsigned char const *sourcestart;
152 unsigned char * deststart;
153 len_mulcand = strlen(mulcand);
154 Multiplicand = malloc( len_mulcand );
155 Multiplicand_end = Multiplicand + len_mulcand - 1;
156 if ( NULL == Multiplicand )
157 return err_Multiplicand;
158
159 sourcestart = mulcand;
160 deststart = Multiplicand;
161 do
162 {
163 *deststart++ = (*sourcestart++) - '0';
164 }while(*sourcestart);
165
166 return err_None;
167 }
168
169 errflag initmulter (unsigned char const *multer)
170 {
171 unsigned char const *sourcestart;
172 unsigned char * deststart;
173 len_multer = strlen(multer);
174 Multiplier = malloc ( len_multer );
175 Multiplier_end = Multiplier + len_multer - 1;
176 if ( NULL == Multiplier )
177 return err_Multiplier;
178
179 sourcestart = multer;
180 deststart = Multiplier;
181
182 do
183 {
184 *deststart++ = (*sourcestart++) - '0';
185 }while(*sourcestart);
186
187 return err_None;
188 }
189
190 errflag initaddonce( )
191 {
192 unsigned char * deststart;
193 len_addonceresult = len_mulcand + 1;
194 AddonceResult = malloc ( len_addonceresult );
195 AddonceResult_end = AddonceResult + len_addonceresult - 1;
196 if ( NULL == AddonceResult )
197 return err_AddonceResult;
198
199 deststart = AddonceResult;
200 while(deststart <= AddonceResult_end)
201 *deststart++ = 0;
202
203 return err_None;
204 }
205
206 errflag initresult ( )
207 {
208 unsigned char * deststart;
209 len_result = len_mulcand + len_multer;
210 AllResult = malloc ( len_result );
211 AllResult_end = AllResult + len_result - 1;
212 if ( NULL == AllResult )
213 return err_AllResult;
214
215 deststart = AllResult;
216 while(deststart <= AllResult_end)
217 *deststart++ = 0;
218
219 return err_None;
220 }