long eval(const char *str) { if(*str=='.') /* accelerated expression */ { if(!num_check(++str)) { /* str is a pure integer */ return (atoi(str)); } else /* PREFIX EQ (linear-operations. exp.) */ { int value = 0; for(;*str>='0'&&*str<='9';str++) value = value*10 + (*str-'0'); return value; } } else /* standard expression */ { if(!num_check(str)) { /* str is a pure integer */ return (atoi(str)); } else /* ordinary infix form equation */ { return 999; } } }
/*************************************************************** * Funciton name: mul * Argv: char num_a[], char num_b[], char product[], * Return: none * Descirption: do multiply, return the result in argv product[] ***************************************************************/ void mul(char num_a[], char num_b[], char product[]) { int index_a = 0; int index_b = 0; int carry = 0; int bit_p = 0; int count = 0; char bit_pro[RESSIZE] = {0}; char tmp_pro[RESSIZE] = {0}; /* handle the special case */ int flag_a = num_check(num_a); int flag_b = num_check(num_b); if (-1 == flag_a || -1 == flag_b) { printf("illegal number\n"); return ; } if (0 == flag_a || 0 == flag_b) { product[0] = '0'; return ; } /* pre-treat numbers */ reverse(num_a); reverse(num_b); /* begin multiply */ for (index_b = 0; '\0' != num_b[index_b]; ++index_b) { for (index_a = 0; '\0' != num_a[index_a]; ++index_a) { bit_p = (num_b[index_b] - '0') * (num_a[index_a] - '0') + carry; carry = bit_p / 10; bit_p = bit_p % 10; bit_pro[index_a] = bit_p + '0'; } if (0 != carry) { bit_pro[index_a++] = carry + '0'; } reverse(bit_pro); for (count = 0; count != index_b; ++count) { bit_pro[index_a] = '0'; ++index_a; } strcpy(tmp_pro, product); memset(product, 0, RESSIZE); add(bit_pro, tmp_pro, product); /* clear the buffers */ memset(tmp_pro, 0, RESSIZE); memset(bit_pro, 0, RESSIZE); } }
/*************************************************************** * Funciton name: add * Argv: char num_a[], char num_b[], char sum[], * Return: none * Descirption: do addition, return the result in argv sum[] ***************************************************************/ void add(char num_a[], char num_b[], char sum[]) { int index = 0; int tmp_sum = 0; int carry = 0; /* handle the special case */ int flag_a = num_check(num_a); int flag_b = num_check(num_b); if (-1 == flag_a || -1 == flag_b) { printf("illegal number\n"); return ; } if (0 == flag_a) { strcpy(sum, num_b); return ; } if (0 == flag_b) { strcpy(sum, num_a); return ; } /* pre-treat the numbers */ reverse(num_a); reverse(num_b); align(num_a, num_b); /* begin addition */ for (index = 0; '\0' != num_a[index]; ++index) { tmp_sum = (num_a[index] - '0') + (num_b[index] - '0') + carry; carry = tmp_sum / 10; tmp_sum = tmp_sum % 10; sum[index] = tmp_sum + '0'; } if (1 == carry) { sum[index] = '1'; sum[++index] = '\0'; } else { sum[index] = '\0'; } reverse(sum); }
static int test_oct_large_num(void) { Val *vals = oct_large_vals; int i, num = sizeof(oct_large_vals)/sizeof(Val); for (i=0; i<num; i++) { if (num_check(&vals[i]) != 0) return 1; } return 0; }
/*************************************************************** * Funciton name: div * Argv: char num_a[], char num_b[], char product[], * Return: none * Descirption: do division, return the result to stdout ***************************************************************/ void div(char num_a[], char num_b[]) { char remain[NUMSIZE] = {0}; char quot[NUMSIZE] = {0}; char mid_rem[NUMSIZE] = {0}; char tmp_rem[NUMSIZE] = {0}; /* handle the special case */ int flag_a = num_check(num_a); int flag_b = num_check(num_b); if (-1 == flag_a || -1 == flag_b) { printf("illegal number\n"); return ; } if (0 == flag_a) { remain[0] = '0'; quot[0] = '0'; printf("quotient: %s\n", quot); printf("remainder: %s\n", remain); return ; } if (0 == flag_b) { printf("zero can't be div\n"); return ; } /* begin division */ int flag = num_cmp(num_a, num_b); /* the two numbers are equal */ if (0 == flag) { remain[0] = '0'; quot[0] = '1'; printf("quotient: %s\n", quot); printf("remainder: %s\n", remain); return ; } /* numerator is smaller than denomerator */ if (-1 == flag) { strcpy(remain, num_a); quot[0] = '0'; printf("quotient: %s\n", quot); printf("remainder: %s\n", remain); return ; } /* normal case */ strcpy(mid_rem, num_a); while (num_cmp(mid_rem, num_b) > 0) { num_inc(quot); sub(mid_rem, num_b, tmp_rem); strcpy(mid_rem, tmp_rem); memset(tmp_rem, 0, NUMSIZE); } /* remainder is 0 */ if (num_cmp(mid_rem, num_b) == 0) { num_inc(quot); remain[0] = '0'; } /* remainder is not 0 */ if (num_cmp(mid_rem, num_b) < 0) { strcpy(remain, mid_rem); } printf("quotient: %s\n", quot); printf("remainder: %s\n", remain); };
/*************************************************************** * Funciton name: sub * Argv: char num_a[], char num_b[], char remain[], * Return: none * Descirption: do subtraction, return the result in argv remain[] ****************************************************************/ void sub(char num_a[], char num_b[], char remain[]) { char big[NUMSIZE] = {0}; char small[NUMSIZE] = {0}; /* handle the special case */ int flag_a = num_check(num_a); int flag_b = num_check(num_b); if (-1 == flag_a || -1 == flag_b) { printf("illegal number\n"); return ; } if (0 == flag_a) { remain[0] = '-'; strcpy(++remain, num_b); return ; } if (0 == flag_b) { strcpy(remain, num_a); return ; } /* find the bigger number, put it in big[],and small one in small[] */ int flag = num_cmp(num_a, num_b); switch (flag) { case 1: strcpy(big, num_a); strcpy(small, num_b); break; case -1: strcpy(big, num_b); strcpy(small, num_a); break; case 0: remain[0] = '0'; return ; default: break; } /* pre-treat numbers */ reverse(big); reverse(small); align(big, small); /* begin subtraction */ int borrow = 0; int index = 0; int bit_a = 0; int bit_b = 0; int bit_r = 0; for (index = 0; '\0' != big[index]; ++index) { bit_a = big[index] - '0'; bit_b = small[index] - '0'; if (0 != bit_a && (bit_a - borrow) >= bit_b) { bit_r = bit_a - borrow - bit_b; borrow = 0; } else if (0 != bit_a && (bit_a - borrow) < bit_b) { bit_r = bit_a - borrow + 10 - bit_b; borrow = 1; } else if (0 == bit_a && 0 == bit_b && 0 == borrow) { bit_r = bit_a - bit_b; borrow = 0; } else { bit_r = bit_a + 10 - bit_b - borrow; borrow = 1; } remain[index] = bit_r + '0'; } /* regulate the result */ while ('0' == remain[--index]) { ; } if (-1 == flag) { remain[++index] = '-'; remain[++index] = '\0'; } remain[++index] = '\0'; reverse(remain); }
void evali(const char *str, char *err, int *eval) { // Mathematical Expression Evaluation Function (INT) // --------------------------------------------------- // This functions solves mathematical expressions // based on integer numbers. When a complex expression // is passed via *str, the expression is broken // into parts, and the simplest part in accordance // with the BODMAS theorum is passed on recursively // onto the function itself. This recurvise process is // repeated until the whole expression has been solved. // Results of the evaluation are stored in int *eval. if((*str=='\0')||(strlen(str)==0)) { strcpy(err,"Void Expression"); return; } int i = 0; /* common loop counter */ char bcheck = 0; for(i=0;*str!='\0';str++,i++) { /* check if there are brackets in an equation. */ if(*str=='('||*str==')') /* bcheck is 0 if there are no brackets & vice-versa. */ { bcheck = 1; break; } } for(;i>0;i--) str--; /* reverse str pointer to original position */ if(!bcheck) { /* this is the core of eval where the calculations are done. at this level, the equation does not have any brackets. */ const char symbols[]="^*/%+-&"; const char se[]="Invalid Syntax"; const char ue[]="Unknown Symbol"; char *tmp = NULL; if((tmp=(char *)(malloc(sizeof(char)* (strlen(str)+1))))==NULL) allocerr(); *tmp='\0'; /* check wether str has reached the absolute stage */ if(prechar(tmp,str,symbols)==0) { /* char to store num_check results */ char ncheck = 0; ncheck = num_check(str); if(!ncheck) { /* str is a number (real or integer) */ *eval = atoi(str); free(tmp); tmp = NULL; return; } else if(!id_check(str)) { free(tmp); tmp = NULL; // char *vals = NULL; // vals = valstr(str); // *eval = atoi(vals); // free(vals); // vals = NULL; *eval = 0; return; } else { /* not a variable, number nor function; hence an error */ strcpy(err,se); strcat(err,": "); strcat(err,str); free(tmp); tmp = NULL; return; } } else /* there are symbols in str */ { free(tmp); tmp = NULL; } /* now the real maths */ char *pre = NULL; /* string preceding the operator */ char *pos = NULL; /* string succeding the operator */ /* now allocate the variables */ if((pre=(char *)(malloc(sizeof(char)* (strlen(str)+1))))==NULL) allocerr(); *pre='\0'; if((pos=(char *)(malloc(sizeof(char)* (strlen(str)+1))))==NULL) allocerr(); *pos='\0'; char symbol = 0; if(prechar(pre,str,"^")) { if(postchar(pos,str,"^")) symbol = '^'; } else if(prechar(pre,str,"*")) { if(postchar(pos,str,"*")) symbol = '*'; } else if(prechar(pre,str,"/")) { if(postchar(pos,str,"/")) symbol = '/'; } else if(prechar(pre,str,"%")) { if(postchar(pos,str,"%")) symbol = '%'; } else if(prechar(pre,str,"+")) { if(postchar(pos,str,"+")) symbol = '+'; } else if(prechar(pre,str,"-")) { if(postchar(pos,str,"-")) symbol = '-'; } else if(prechar(pre,str,"&")) { if(postchar(pos,str,"&")) symbol = '&'; } else { strcpy(err,ue); strcat(err,": "); *++err=symbol; *++err='\0'; return; } char *ax = NULL; /* value preceding of operator */ char *bx = NULL; /* value succeding the operator */ char *cx = NULL; /* value of ax and bx processed */ /* now allocate ax and bx */ if((ax=(char *)(malloc(sizeof(char)* (strlen(pre)+1))))==NULL) allocerr(); *ax='\0'; if((bx=(char *)(malloc(sizeof(char)* (strlen(pos)+1))))==NULL) allocerr(); *bx='\0'; /* find out the contents of bx */ char *ebx = NULL; /* temp string to build bx */ if((ebx=(char *)(malloc(sizeof(char)* (strlen(pos)+1))))==NULL) allocerr(); *ebx='\0'; strcpy(bx,pos); strcpy(ebx,bx); for(;;) /* infinite loop */ { if(!prechar(bx,ebx,symbols)) { strcpy(bx,ebx); free(ebx); ebx = NULL; /* de-allocate ebx */ break; } else /* here ebx is build */ strcpy(ebx,bx); } /* find out the contents of ax */ char *eax = NULL; /* temp string to build ax */ if((eax=(char *)(malloc(sizeof(char)* (strlen(pre)+1))))==NULL) allocerr(); *eax='\0'; strcpy(ax,pre); strcpy(eax,ax); for(;;) /* infinite loop */ { if(!postchar(ax,eax,symbols)) { strcpy(ax,eax); free(eax); eax = NULL; /* de-allocate eax */ break; } else /* here eax is build */ strcpy(eax,ax); } /* variables to store (pre-ax) and (pre-bx) */ char *prex = NULL; /* string of (pre-ax) */ char *posx = NULL; /* string of (pos-ax) */ /* now allocate prex and posx */ if((prex=(char *)(malloc(sizeof(char)* (strlen(pre)+1))))==NULL) allocerr(); *prex='\0'; if((posx=(char *)(malloc(sizeof(char)* (strlen(pos)+1))))==NULL) allocerr(); *posx='\0'; /* find prex and posx */ strlft(prex,pre,(strlen(pre)-strlen(ax))); strrht(posx,pos,(strlen(pos)-strlen(bx))); /* de-allocate pre & pos */ free(pre); pre = NULL; free(pos); pos = NULL; /* process ax and bx to find cx */ // printf("\nax=%s",ax); // printf("\nbx=%s",bx); int evala=0; int evalb=0; int evalc=0; if(num_check(ax)) { // tmp = valstr(ax); // if((cp=(char *)(realloc(ax,sizeof(char)* // (strlen(tmp)+1))))!=NULL) { ax = cp; } // else { allocerr(); } // strcpy(ax,tmp); // free(tmp); // tmp = NULL; strcpy(ax,""); } if(num_check(bx)) { // tmp = valstr(bx); // if((cp=(char *)(realloc(bx,sizeof(char)* // (strlen(tmp)+1))))!=NULL) { bx = cp; } // else { allocerr(); } // strcpy(bx,tmp); // free(tmp); // tmp = NULL; strcpy(bx,""); } evala = atoi(ax); evalb = atoi(bx); switch(symbol) { case '^': /* power */ evalc = (int)(pow(evala,evalb)); break; case '*': /* multiplication */ evalc = evala * evalb; break; case '/': /* division */ evalc = evala / evalb; break; case '%': /* modulus */ evalc = evala % evalb; break; case '+': /* addition */ evalc = evala + evalb; break; case '-': /* subtraction */ evalc = evala - evalb; break; case '&': /* concatenation */ if((cp=(char *)(realloc(cx,sizeof(char)* (strlen(ax)+strlen(bx)+1))))!=NULL) { cx = cp; } else { allocerr(); } strcpy(cx,ax); strcat(cx,bx); evalc = atoi(cx); break; default: strcpy(err,ue); strcat(err,": "); *++err=symbol; *++err='\0'; return; } /* find the length of evalc */ int cxlen = 8; if(evalc<0) { cxlen = 16; } else if(evalc==0) { cxlen = 2; } else { cxlen = 0; int ctmp = evalc; while(ctmp>0) { ctmp/=10; cxlen++; } } /* allocate cx having the length of evalc */ if((cx=(char *)(malloc(sizeof(char)* ((cxlen)+1))))==NULL) allocerr(); *cx='\0'; itoa(evalc,cx,10); // printf("\ncx=%s\n",cx); /* de-allocate ax & bx */ free(ax); ax = NULL; free(bx); bx = NULL; /* variable to store one-step solved equation */ char *ex = NULL; if((ex=(char *)(malloc(sizeof(char)* (strlen(prex)+strlen(cx)+strlen(posx)+1))))==NULL) allocerr(); *ex='\0'; /* find ex using cx in prex and posx */ strcpy(ex,prex); strcat(ex,cx); strcat(ex,posx); /* now de-allocate cx, prex & posx */ free(cx); cx = NULL; free(prex); prex = NULL; free(posx); posx = NULL; /* recurse ex on eval for next-step solving */ int integer=0; evali(ex,err,&integer); *eval = integer; /* de-allocate ex & return */ free(ex); ex = NULL; return; } else { // check if an equation is correct in no. of brackets. unsigned int brackets[2]={0,0}; for(i=0;*str!='\0';str++,i++) { /* find the no. of brackets */ if(*str=='(') brackets[0]+=1; if(*str==')') brackets[1]+=1; } for(;i>0;i--) str--; /* reverse str pointer to original position */ if(brackets[0]==brackets[1]) { char *pres = NULL; char *poss = NULL; char *mids = NULL; char *midx = NULL; char *newx = NULL; /* now allocate the above string */ if((pres=(char *)(malloc(sizeof(char)* (strlen(str)+1))))==NULL) allocerr(); *pres='\0'; if((poss=(char *)(malloc(sizeof(char)* (strlen(str)+1))))==NULL) allocerr(); *poss='\0'; if((mids=(char *)(malloc(sizeof(char)* (strlen(str)+1))))==NULL) allocerr(); *mids='\0'; if((midx=(char *)(malloc(sizeof(char)* (strlen(str)+1))))==NULL) allocerr(); *midx='\0'; if((newx=(char *)(malloc(sizeof(char)* (strlen(str)+1))))==NULL) allocerr(); *newx='\0'; /* now split the string */ unsigned long int cs = 0; unsigned long int bcount = 0; /* make pres */ for(cs=0;*str!='\0';cs++) { if(*str=='(') bcount++; if(bcount==brackets[0]) break; *pres++ = *str++; } for(*pres = '\0';cs>0;cs--) pres--; /* make mids */ for(cs=0,str++;((*str!=')')&&(*str!='\0'));cs++) *mids++ = *str++; for(*mids = '\0';cs>0;cs--) mids--; /* make poss */ for(cs=0,str++;*str!='\0';cs++) *poss++ = *str++; for(*poss = '\0';cs>0;cs--) poss--; /* ok, now evaluate */ int integer = 0; evali(mids,err,&integer); itoa(integer,midx,10); strcpy(newx,pres); strcat(newx,midx); strcat(newx,poss); evali(newx,err,&integer); *eval = integer; return; } else { strcpy(err,"Invalid Equation, inequal number of brackets."); return; } } }