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. |