5752043 [rkeene@sledge /home/rkeene/devel/old/vmpu]$ cat -n vmpu.c
  1 /*
  2    My VMPU routines... in C.
  3    -- RKeene [06/10/1999:14:00]  
  4    rkeene@netfueldesign.com
  5 
  6    Synopsis of procedures status:
  7    name     | status
  8    ----------------+-------------------------------------------------
  9    add()        | works ok with no decimals.
 10    mul()        | works ok with no decimals.
 11    sub()        | works ok with no decimals, needs to be rewritten.
 12    div()        | doesnt do anything.
 13    pwr()        | doesnt do anything.
 14    addlead()    | works ok.
 15    addtrail()   | works ok.
 16    striplead()  | works ok.
 17    isgreater()  | works ok, with no decimals.
 18    cleararray() | works ok, slow.
 19    ---------------/ \------------------------------------------------
 20 */
 21 #include <string.h>
 22 #include <stdio.h>
 23 #include <stdlib.h>
 24 #include <math.h>
 25 #define     LIMIT       8192
 26 #define     DEBUG       0
 27 
 28 void add();
 29 void sub();
 30 void mul();
 31 void divd();
 32 
 33 void cleararray(char n[LIMIT])
 34 {
 35    int i;
 36    for (i=0;i<LIMIT;i++)
 37    {
 38       n[i]=0;
 39    }
 40 }
 41 
 42 void addlead(int n, char f, char t[LIMIT])
 43 {
 44    int i;
 45    int m;
 46    char tmp[LIMIT];
 47    cleararray(tmp);
 48    m=strlen(t);
 49    for(i=0;i<n;i++)
 50    {
 51       tmp[i]=f;
 52    }
 53    for (i=i;i<(n+m);i++)
 54    {
 55       tmp[i]=t[i-n];
 56    }
 57 #if DEBUG>=3
 58    printf("addlead returning %s\n",tmp);
 59 #endif
 60    strcpy(t,tmp);
 61 }
 62 
 63 void addtrail(int n, char f, char t[LIMIT])
 64 {
 65    int i;
 66    int m;
 67    char tmp[LIMIT];
 68    cleararray(tmp);
 69    m=strlen(t);
 70    if (DEBUG>=3) printf("addtrail(%i,%i,%s) -> ",n,f,t);
 71    for(i=0;i<m;i++)
 72    {
 73       tmp[i]=t[i];
 74    }
 75    for (i=i;i<(n+m);i++)
 76    {
 77       tmp[i]=f;
 78    }
 79    if (DEBUG==3) printf("addtrail returning %s\n",tmp);
 80    strcpy(t,tmp);
 81 }
 82 
 83 
 84 /*
 85    Strip leading 0's from a numeric string.
 86    sets X to the string.
 87 */
 88 void striplead(char x[LIMIT], char n[LIMIT])
 89 {
 90    char tmp[LIMIT];
 91    int i,sizeofn;
 92    int begin=-1, neg=0;
 93    sizeofn=strlen(n);
 94    if (n[0]=='-') {  neg=1; n[0]='0';  }
 95    for (i=0;i<sizeofn;i++)
 96    {
 97       if (n[i]!='0' && begin==-1) {  begin=i;  }
 98       if (begin!=-1) {  tmp[i-begin]=n[i];  }
 99    }
100    if (begin!=-1) {  tmp[(i-begin)]=0;  } else {  tmp[0]='0'; tmp[1]=0;  }
101    cleararray(x);
102    if (neg==1) {  sprintf(x,"%c%s",'-',tmp); n[0]='-';  } else {  strcpy(x,tmp);  }
103 }
104 
105 
106 int isgreater(char n1[LIMIT], char n2[LIMIT])
107 {
108    char tmp1[LIMIT];
109    char tmp2[LIMIT];
110    int sizeofn1,sizeofn2,i,tmpc1,tmpc2,neg=0;
111    striplead(tmp1,n1);
112    striplead(tmp2,n2);
113    if (tmp1[0]=='-') {  neg+=10; tmp1[0]='0';  }
114    if (tmp2[0]=='-') {  neg+=1; tmp1[0]='0';  }
115    if (neg==1) {  return(1);  }
116    if (neg==10) {  return(2);  }
117    sizeofn1=strlen(tmp1);
118    sizeofn2=strlen(tmp2);
119    if (sizeofn1>sizeofn2) return(1);
120    if (sizeofn1<sizeofn2) return(2);
121    for (i=0;i<sizeofn1;i++)
122    {
123       tmpc1=tmp1[i]-48;
124       tmpc2=tmp2[i]-48;
125       if (tmpc1>tmpc2) {  return(1);  }
126       if (tmpc1<tmpc2) {  return(2);  }
127    }
128    return 0;
129 }
130 
131 
132 void add(char n1[LIMIT], char n2[LIMIT])
133 {
134    char tmp1[LIMIT];
135    char tmp2[LIMIT];
136    char tmp3[LIMIT];
137    int tmpc1;
138    int tmpc2;
139    int sizeofn1;
140    int sizeofn2;
141    int diff;
142    int i;
143    int remain=0;
144    int val,neg=0;
145    sizeofn1=strlen(n1);
146    sizeofn2=strlen(n2);
147    cleararray(tmp1);
148    strcpy(tmp2,tmp1);
149    strcpy(tmp3,tmp1);
150    if(DEBUG>=1) printf("Adding %s(%i) and %s(%i)\n",n1,sizeofn1,n2,sizeofn2);
151    diff=abs(sizeofn1-sizeofn2);
152    strcpy(tmp1,n1);
153    strcpy(tmp2,n2);
154    if (tmp1[0]=='-') {  neg+=1; tmp1[0]='0';  }
155    if (tmp2[0]=='-') {  neg+=10; tmp2[0]='0';  }
156    if (neg==10) {  (void) sub(tmp1,tmp2); strcpy(n1,tmp1); return;  }
157    if (neg==1) {  (void) sub(tmp2,tmp1); strcpy(n1,tmp2);
158           printf("-->%s (%s)",n1,tmp2);
159           return;  }
160    if (sizeofn1<sizeofn2) {  addlead(diff,'0',tmp1);  }
161    if (sizeofn1>sizeofn2) {  addlead(diff,'0',tmp2);  }
162    if (DEBUG>=1) printf ("  %s\n+ %s\n",tmp1,tmp2);
163    sizeofn2=strlen(tmp2);
164    for (i=(sizeofn2-1);i>=0;i--)
165    {
166       tmpc1=tmp1[i];
167       tmpc2=tmp2[i];
168       if (tmpc1<48 || tmpc1>57 || tmpc2<48 || tmpc2>57) {  i=0;  }
169       val=((tmpc1-48)+(tmpc2-48)+remain);
170       if (val>9) {  val -= 10; remain=1;  } else {  remain = 0;  }
171       if (DEBUG>=2) {  printf ("%i) %i rem %i (%i,%i)\n",i,val,remain,tmpc1-48,tmpc2-48);  }
172       tmp3[i]=(val+48);
173    }
174    tmp3[sizeofn2]=0;
175    if (neg==11) {  sprintf(n1,"%c%s",'-',tmp3);  } else {  strcpy(n1,tmp3);  }
176 #if DEBUG>=1
177    printf("  %s\n",n1);
178 #endif
179 }
180 
181 void mul(char n1[LIMIT], char n2[LIMIT])
182 {
183    char tmp1[LIMIT];
184    char tmp2[LIMIT];
185    char tmp3[LIMIT];
186    char tmp4[LIMIT];
187    char offset[LIMIT];
188    int sizeofn1;
189    int sizeofn2;
190    int i,q,tmpc1,tmpc2,val,remain,neg=0;
191 #if DEBUG>=1
192    printf("Multiplying %s by %s...\n",n1,n2);
193 #endif
194    cleararray(tmp1);
195    strcpy(tmp2,tmp1);
196    strcpy(tmp3,tmp1);
197    strcpy(tmp4,tmp1);
198    strcpy(offset,tmp1);
199    if (strlen(n1)>=strlen(n2)) {  strcpy(tmp1,n1); strcpy(tmp2,n2);  }
200    if (strlen(n1)<strlen(n2)) {  strcpy(tmp1,n2); strcpy(tmp2,n1);  }
201    if (tmp1[0]=='-') {  tmp1[0]='0'; neg+=1;  }
202    if (tmp2[0]=='-') {  tmp2[0]='0'; neg+=1;  }
203 #if DEBUG>=1
204    printf("  %s\n* %s\n",tmp1,tmp2);
205 #endif
206    sizeofn1=strlen(tmp1);
207    sizeofn2=strlen(tmp2);
208    for (i=(sizeofn2-1);i>=0;i--)
209    {
210       tmp4[0]='0';
211       remain=0;
212       for (q=(sizeofn1-1);q>=0;q--)
213       {
214      tmpc1=tmp1[q]-48;
215      tmpc2=tmp2[i]-48;
216      val=(tmpc1*tmpc2)+remain;
217      if (val>9) {  remain=val/10; val-=remain*10;  } else {  remain = 0;  }
218      tmp4[q+1]=val+48;
219 #if DEBUG>=2
220      printf("%i,%i) %i,%i=%i rem %i\n",i,q,tmpc1,tmpc2,val,remain);
221 #endif
222       }
223       tmp4[0]=remain+48;
224       tmp4[sizeofn1+1]=0;
225       addtrail(((i-sizeofn2)*-1)-1,'0',tmp4);
226 #if (DEBUG>=2)
227      printf("%s(%i) (%s(%i))\n",tmp4,(int) strlen(tmp4),tmp3,(int) strlen(tmp3));
228 #endif
229       add(tmp3,tmp4);
230    }
231    if (neg==1) {  sprintf(n1,"%c%s",'-',tmp3);  } else {  strcpy(n1,tmp3);  }
232 #if DEBUG>=1
233    printf("  %s(%i)\n",n1,(int) strlen(n1));
234 #endif
235 }
236 
237 void sub(char n1[LIMIT], char n2[LIMIT])
238 {
239    char tmp1[LIMIT];
240    char tmp2[LIMIT];
241    char tmp3[LIMIT];
242    int borrow=0;
243    int neg=0, nega=0;
244    int i,tmpc1,tmpc2,val,diff,greater;
245    int sizeofn1,sizeofn2;
246 #if (DEBUG>=1)
247       printf("Sub calculating %s(%i)-%s(%i)...\n",n1,sizeofn1,n2,sizeofn2);
248 #endif
249    greater=isgreater(n1,n2);
250    if (greater==2) {
251               neg=1;
252               strcpy(tmp1,n2);
253               strcpy(tmp2,n1);
254            } else {
255                  neg=0;
256                  strcpy(tmp1,n1);
257                  strcpy(tmp2,n2);
258               }
259    if (tmp1[0]=='-') {  tmp1[0]='0'; nega+=10;  }
260    if (tmp2[0]=='-') {  tmp2[0]='0'; nega+=1;  }
261    if (nega==11) {  tmp1[0]='-'; add(tmp1,tmp2); strcpy(n1,tmp1); return;  }
262    if (neg==1 && nega==1) {  add(tmp1,tmp2); sprintf(n1,"%c%s",'-',tmp1); return;  }
263    if (neg==0 && nega==1) {  add(tmp1,tmp2); strcpy(n1,tmp1); return;  }
264    sizeofn1=strlen(tmp1);
265    sizeofn2=strlen(tmp2);
266    diff=abs(sizeofn1-sizeofn2);
267    if (sizeofn1<sizeofn2) {  addlead(diff,'0',tmp1);  }
268    if (sizeofn1>sizeofn2) {  addlead(diff,'0',tmp2);  }
269 #if (DEBUG>=1)
270    {  printf("  %s\n- %s\n",tmp1,tmp2);  }
271 #endif
272    for (i=strlen(tmp1)-1;i>-1;i--)
273    {
274       tmpc1=tmp1[i]-48;
275       tmpc2=tmp2[i]-48;
276       val=tmpc1-tmpc2-borrow;
277       borrow=0;
278       if (val<0 && i==0) {  neg=1;  }
279       if (val<0) {  borrow=1; val+=10;  };
280 #if (DEBUG>=2)
281       {  printf("%i) %i,%i=%i\n",i,tmpc1,tmpc2,val);  }
282 #endif
283       tmp3[i+1]=val+48;
284    }
285 /*
286       sprintf(tmp3,"%i%s",borrow,tmp3);
287 */
288    if (neg==1) {  tmp3[0]='-';  } else {  tmp3[0]='0';  }
289 #if (DEBUG>=1)
290    {  printf("  %s\n",tmp3);  }
291 #endif
292    tmp3[sizeofn1+1]=0;
293    strcpy(n1,tmp3);
294 }
295 
296 void divd(char n1[LIMIT], char n2[LIMIT]) {
297 
298                       }
299 
300 void pwr(char n1[LIMIT],char n2[LIMIT])
301 {
302    char tmp[LIMIT], dec[2];
303    strcpy(dec,"1");
304    strcpy(tmp,n1);
305    sub(n2,dec);
306    while(isgreater(n2,"0")==1)
307    {
308       sub(n2,dec);
309       striplead(n2,n2);
310 /*
311      printf("%s... %s... %s\n",n2,n1,dec);
312 */
313       mul(n1,tmp);
314       striplead(n1,n1);
315    }
316 }
317 
318 
319 int main(int argc, char *argv[])
320 {
321    char nm1[LIMIT], nm2[LIMIT];
322    if (argc<=3) {  printf("Usage:\t%s {add|sub|mul|div|pwr} {number} {number}\n",argv[0]); return(1);  }
323    strcpy(nm1,argv[2]);
324    strcpy(nm2,argv[3]);
325    if (strncmp("add",argv[1],3)==0) {  add(nm1,nm2);  }
326    if (strncmp("sub",argv[1],3)==0) {  sub(nm1,nm2);  }
327    if (strncmp("mul",argv[1],3)==0) {  mul(nm1,nm2);  }
328    if (strncmp("pwr",argv[1],3)==0) {  pwr(nm1,nm2);  }
329    if (strncmp("div",argv[1],3)==0) {  divd(nm1,nm2);  }
330    striplead(nm1,nm1);
331    printf("Result=%s\n",nm1);
332    return(0);
333 }

vmpu.c is the source code.
5752044 [rkeene@sledge /home/rkeene/devel/old/vmpu]$

Click here to go back to the directory listing.
Click here to download this file.
last modified: 2000-02-06 08:32:31