You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
382 lines
8.9 KiB
C
382 lines
8.9 KiB
C
/* ------------------------------------------------------------------------- */
|
|
#include <math.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
/* ------------------------------------------------------------------------- */
|
|
double getbinary(char *str,int *ptr)
|
|
{
|
|
double bin=0;
|
|
|
|
while (*str=='0' || *str=='1')
|
|
{
|
|
bin = (bin*2) + (*str++ -'0');
|
|
*ptr += 1;
|
|
}
|
|
|
|
return (bin);
|
|
};
|
|
/* ------------------------------------------------------------------------- */
|
|
|
|
double getdecimal(char *str,int *ptr)
|
|
{
|
|
|
|
double dec=0;
|
|
int i=0,end=0,neg=0,fraction=0;
|
|
|
|
if (str[i]=='-') {neg=1;i++;};
|
|
|
|
do {
|
|
|
|
if ((str[i] >='0') && (str[i] <='9'))
|
|
dec = (dec * 10) + (str[i] - '0');
|
|
else if (str[i] == '.') fraction=i;
|
|
else end=1;
|
|
|
|
i++;
|
|
} while(!end);
|
|
|
|
if (neg)
|
|
dec *= -1;
|
|
if (fraction)
|
|
dec = dec/pow(10,(i-2-fraction));
|
|
|
|
|
|
*ptr=*ptr+i-1;
|
|
|
|
return (dec);
|
|
|
|
};
|
|
|
|
|
|
|
|
/**************/
|
|
|
|
double gethexa(char *str,int *ptr){
|
|
|
|
double hex=0;
|
|
int end=0;
|
|
|
|
while (*str && !end)
|
|
{
|
|
if ((*str >='0') && (*str <='9'))
|
|
hex = (hex * 16) + (*str - '0');
|
|
else if ((*str >='a') && (*str <= 'f'))
|
|
hex = (hex * 16) + (*str - 'a' + 10);
|
|
else if ((*str >='A') && (*str <= 'F'))
|
|
hex = (hex * 16) + (*str - 'A' + 10);
|
|
else end = 1;
|
|
|
|
if (!end)
|
|
{
|
|
str++;
|
|
*ptr += 1;
|
|
}
|
|
}
|
|
|
|
return (hex);
|
|
|
|
};
|
|
|
|
/*******************************************************************/
|
|
|
|
void veremcompress(char * verem,double * szamok,int begin,int * end){
|
|
|
|
/*
|
|
* Az adott tartomanyban a verembol kiszedi a felesleges zarojeleket,
|
|
* es az ures (' ') bejegyzeseket
|
|
*
|
|
*/
|
|
|
|
int i,j,lyuk;
|
|
int zarojel,job;
|
|
|
|
// kiszedem a lyukakat, aztan a zarjeleket, aztan megint lyuk, es igy tovabb...
|
|
|
|
|
|
do {
|
|
job=0;
|
|
|
|
// lyukszedes:
|
|
do {
|
|
lyuk=0;
|
|
for (i=begin;i<=*end;i++) {
|
|
if (verem[i]==' ') {
|
|
lyuk=1;
|
|
for (j=i;j<*end;j++) {verem[j]=verem[j+1];
|
|
szamok[j]=szamok[j+1];};
|
|
verem[j]=' ';
|
|
(*end)--;
|
|
};
|
|
};
|
|
} while (lyuk);
|
|
|
|
// a felesleges zarojeleket szedem ki:
|
|
zarojel=0;
|
|
for (i=begin;i<=*end;i++) {if (verem[i]=='(') {if (verem[i+1]==')') {verem[i]=' ';
|
|
verem[i+1]=' ';
|
|
job=1;} else
|
|
if (verem[i+1]=='1' && verem[i+2]==')') {verem[i]=' ';
|
|
verem[i+2]=' ';
|
|
job=1;} else
|
|
zarojel++;
|
|
};
|
|
if (verem[i]==')') zarojel--;
|
|
};
|
|
if (zarojel!=0) {printf("Zarojelezesi hiba!\n");exit(-1);};
|
|
} while (job);
|
|
|
|
//ellenorzom, hogy van-e ket szam egymas mogott, hogy nincs koztuk muveleti jel.
|
|
//ilyen nem lehet alapbol, tehat input string hiba
|
|
|
|
for (i=begin;i<*end;i++) if (verem[i]=='1' && verem[i+1]=='1') {printf("Bemeneti stringben hiba!\n");exit(-1);};
|
|
|
|
|
|
};
|
|
|
|
/*******************************************************************/
|
|
|
|
double getnumber(char *verem,double *szamok,int begin,int end){
|
|
|
|
int i,j,zarojel,job;
|
|
|
|
|
|
//Eloszoris az indulaskor is lehetseges felesleges szokozoket, es a felesleges zarojeleket szurom ki:
|
|
//Ha a zarojelezesben hiba van, az is kiderul itt!
|
|
veremcompress(verem,szamok,begin,&end);
|
|
|
|
//Azutan eloszor a zarojelben levo dolgokat szamolom ki, hogy vegul egy () se maradjon.
|
|
|
|
do {
|
|
job=0;
|
|
for (i=begin;i<=end;i++) {if ((verem[i]=='(') || (verem[i]==')')) job=1;};
|
|
if (job) {for (i=begin;verem[i]!='(';i++);
|
|
j=i;zarojel=1;
|
|
do {j++;
|
|
if (verem[j]=='(') zarojel++;
|
|
if (verem[j]==')') zarojel--;
|
|
} while(zarojel!=0);
|
|
getnumber(verem,szamok,i+1,j-1);
|
|
verem[i]=' ';
|
|
verem[j]=' ';
|
|
veremcompress(verem,szamok,begin,&end);
|
|
};
|
|
} while(job!=0);
|
|
|
|
|
|
// Mostmar garantaltan nincs zarojel, johet sorrendben a tovabbi szamolas:
|
|
|
|
|
|
while(begin!=end) {
|
|
|
|
// Elso korben HATVANYozast keresek.
|
|
|
|
for (i=begin;i<=end;i++) {if (verem[i]=='^') {
|
|
szamok[i]=pow(szamok[i-1],szamok[i+1]);
|
|
verem[i]='1';
|
|
verem[i-1]=' ';
|
|
verem[i+1]=' ';
|
|
veremcompress(verem,szamok,begin,&end);
|
|
};
|
|
};
|
|
|
|
// Masodik korben a SZORZASokkal es az OSZTASokkal vegzek
|
|
|
|
for (i=begin;i<=end;i++) {if (verem[i]=='*') {szamok[i]=szamok[i-1]*szamok[i+1];
|
|
verem[i]='1';
|
|
verem[i-1]=' ';
|
|
verem[i+1]=' ';
|
|
veremcompress(verem,szamok,begin,&end);
|
|
};
|
|
if (verem[i]=='/') {szamok[i]=szamok[i-1]/szamok[i+1];
|
|
verem[i]='1';
|
|
verem[i-1]=' ';
|
|
verem[i+1]=' ';
|
|
veremcompress(verem,szamok,begin,&end);
|
|
};
|
|
};
|
|
|
|
// Harmadik korben az OSSZEADAS es a KIVONAS van mar csak
|
|
|
|
for (i=begin;i<=end;i++) {if (verem[i]=='+') {szamok[i]=szamok[i-1]+szamok[i+1];
|
|
verem[i]='1';
|
|
verem[i-1]=' ';
|
|
verem[i+1]=' ';
|
|
veremcompress(verem,szamok,begin,&end);
|
|
};
|
|
if (verem[i]=='-') {szamok[i]=szamok[i-1]-szamok[i+1];
|
|
verem[i]='1';
|
|
verem[i-1]=' ';
|
|
verem[i+1]=' ';
|
|
veremcompress(verem,szamok,begin,&end);
|
|
};
|
|
};
|
|
};
|
|
|
|
return(szamok[begin]);
|
|
};
|
|
|
|
|
|
/*******************************************************************/
|
|
|
|
|
|
const char* calc(char *kifejezes,double * result){
|
|
|
|
double *szamok;
|
|
char *verem;
|
|
int i,veremp,job,j;
|
|
char *expr;
|
|
char *err;
|
|
|
|
char *ptr;
|
|
|
|
// First I remove the spaces from the expression
|
|
|
|
if (NULL==(expr=(char*)calloc(strlen(kifejezes),1)))
|
|
{
|
|
printf("Out of memory!\n");
|
|
exit(-1);
|
|
};
|
|
|
|
ptr = expr;
|
|
while (*kifejezes) // strip spaces
|
|
{
|
|
if (*kifejezes != ' ')
|
|
*ptr++ = *kifejezes;
|
|
|
|
kifejezes++;
|
|
}
|
|
|
|
*ptr++ = 0;
|
|
|
|
if ( NULL == (verem=(char*)malloc( strlen(expr)+1 )) )
|
|
{
|
|
printf("Out of memory!\n");
|
|
exit(-1);
|
|
};
|
|
if ( NULL == (szamok=(double*)malloc( (strlen(expr)+1) * sizeof(double) )) )
|
|
{
|
|
printf("Out of memory!\n");
|
|
exit(-1);
|
|
};
|
|
|
|
/*
|
|
* Beolvasom a expr-bol a szamokat, es a muveleti jeleket.
|
|
*
|
|
* Veremtartalom a kifejezesben levo elemeket tartalmazza:
|
|
*
|
|
* (,),+,-,*,/,^ A szokasos muveleti jelek (es csak ezek!)
|
|
* 1 : ezen a helyen egy szam all, a szamok altal tartalmazott tombbol keresheto ki, melyik.
|
|
*
|
|
*/
|
|
|
|
|
|
//A legelso karakter nem lehet barmi, kulon vizsgalom:
|
|
i=veremp=0;
|
|
switch(expr[i]) {
|
|
case '(' : verem[veremp++]='(';i++;break;
|
|
case ')' : return ("zarojelezesi hiba");
|
|
break;
|
|
case '0' :
|
|
case '1' :
|
|
case '2' :
|
|
case '3' :
|
|
case '4' :
|
|
case '5' :
|
|
case '6' :
|
|
case '7' :
|
|
case '8' :
|
|
case '9' : verem[veremp]='1'; szamok[veremp++]=getdecimal(&expr[i],&i); break;
|
|
case '+' : verem[veremp]='1'; szamok[veremp++]=getdecimal(&expr[++i],&i); break;
|
|
case '-' : verem[veremp]='1'; szamok[veremp++]=getdecimal(&expr[i],&i); break;
|
|
case '%' : verem[veremp]='1'; i++; szamok[veremp++]=getbinary(&expr[i],&i); break;
|
|
case '$' : verem[veremp]='1'; i++; szamok[veremp++]=gethexa(&expr[i],&i); break;
|
|
default : return ("hiba0");
|
|
};
|
|
|
|
if (strlen(expr)!=i)
|
|
//most a tovabbi karakterek johetnek:
|
|
do {
|
|
if ((verem[veremp-1]=='1') ||
|
|
(verem[veremp-1]==')')) {
|
|
switch(expr[i]) {
|
|
|
|
case ')':
|
|
case '+':
|
|
case '-':
|
|
case '*':
|
|
case '/':
|
|
case '^':
|
|
verem[veremp++]=expr[i++];
|
|
break;
|
|
default:
|
|
return ("hiba1");
|
|
|
|
};
|
|
};
|
|
if (verem[veremp-1]=='(') {
|
|
switch(expr[i]) {
|
|
case '(' : verem[veremp++]='(';i++;break;
|
|
case ')' : verem[veremp++]=')';i++;break;
|
|
case '0' :
|
|
case '1' :
|
|
case '2' :
|
|
case '3' :
|
|
case '4' :
|
|
case '5' :
|
|
case '6' :
|
|
case '7' :
|
|
case '8' :
|
|
case '9' : verem[veremp]='1'; szamok[veremp++]=getdecimal(&expr[i],&i); break;
|
|
case '+' : verem[veremp]='1'; szamok[veremp++]=getdecimal(&expr[++i],&i); break;
|
|
case '-' : verem[veremp]='1'; szamok[veremp++]=getdecimal(&expr[i],&i); break;
|
|
case '%' : verem[veremp]='1'; i++; szamok[veremp++]=getbinary(&expr[i],&i); break;
|
|
case '$' : verem[veremp]='1'; i++; szamok[veremp++]=gethexa(&expr[i],&i); break;
|
|
default : return ("hiba2");
|
|
|
|
};
|
|
};
|
|
if ((verem[veremp-1]=='^') ||
|
|
(verem[veremp-1]=='*') ||
|
|
(verem[veremp-1]=='/') ||
|
|
(verem[veremp-1]=='+') ||
|
|
(verem[veremp-1]=='-')) {
|
|
switch(expr[i]) {
|
|
case '(' : verem[veremp++]='(';i++;break;
|
|
case '0' :
|
|
case '1' :
|
|
case '2' :
|
|
case '3' :
|
|
case '4' :
|
|
case '5' :
|
|
case '6' :
|
|
case '7' :
|
|
case '8' :
|
|
case '9' : verem[veremp]='1'; szamok[veremp++]=getdecimal(&expr[i],&i); break;
|
|
case '+' : verem[veremp]='1'; szamok[veremp++]=getdecimal(&expr[++i],&i); break;
|
|
case '-' : verem[veremp]='1'; szamok[veremp++]=getdecimal(&expr[i],&i); break;
|
|
case '%' : verem[veremp]='1'; i++; szamok[veremp++]=getbinary(&expr[i],&i); break;
|
|
case '$' : verem[veremp]='1'; i++; szamok[veremp++]=gethexa(&expr[i],&i); break;
|
|
default : return ("hiba3");
|
|
};
|
|
|
|
};
|
|
|
|
} while (i<strlen(expr));
|
|
|
|
veremp--; //Ez mindig az utolso ervenyes verem-char-ra indexel ra!
|
|
|
|
*result=getnumber(verem,szamok,0,veremp);
|
|
|
|
free(szamok);
|
|
free(verem);
|
|
free(expr);
|
|
|
|
return(NULL);
|
|
|
|
};
|
|
|
|
/* ------------------------------------------------------------------------- */
|
|
|