home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turbo Toolbox
/
Turbo_Toolbox.iso
/
1991
/
04
/
txl
/
1_preis
/
formel.c
< prev
next >
Wrap
Text File
|
1991-03-06
|
18KB
|
693 lines
/************************************************************************
* ....................................... *
* . . *
* . TOOLBOX - INTERPRETER . *
* . TESTPROGRAMM FÜR WINDOWS-FUNKTIONEN . *
* . FORMEL.C . *
* . M.Beising & K.Bauer & TOOLBOX . *
* ....................................... *
*************************************************************************/
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#include "kubasic.h"
PTNODE CreateTree(char Fktzeile[],int *ErrorPos,int *ErrorNr);
PTNODE faktor(char f[]);
PTNODE vorzfaktor(char f[]);
PTNODE potenz(char f[]);
PTNODE produkt(char f[]);
PTNODE summe(char f[]);
PTNODE vergleich(char f[]);
PTNODE verknuepf(char f[]);
void DelTree(PTNODE *ptnode);
void nextchar(int start,char f[]);
void neuewurzel(PTNODE *wurzel,char f[]);
void newnode(PTNODE *knoten);
BOOL unaerefunktion(char f[],unsigned char *token);
void getnumber(char f[],int *posi,char fhelp[30]);
double Calc(PTNODE *ptnode);
double arctanh(double x);
double arccot(double x);
double cot(double x);
double frac(double f);
float ran1(void);
float ran2(void);
float ran3(void);
float random();
void LiesDaten(void);
void SaveDaten(void);
extern char *GetFileName (void);
extern int AktPos,ErrTyp,ErrPos,ErrNr,fio;
extern BOOL TreeError;
extern HWND hWndglob,hWndEdit;
extern char FileName[FNAMLEN];
extern HANDLE hEditText;
extern OFSTRUCT fileInfo;
extern BOOL bText;
unsigned char aktchar;
PTNODE CreateTree(char Fktzeile[],int *ErrorPos,int *ErrorNr)
{
PTNODE wurzel;
AktPos=0;
nextchar(AktPos,Fktzeile);
TreeError=FALSE;
wurzel=NULL;
wurzel=verknuepf(Fktzeile);
if ((AktPos<=strlen(Fktzeile)) && (Fktzeile[AktPos-1]!=' ') && (!TreeError)) {
TreeError=TRUE;
ErrTyp=4;
}
if (!TreeError) {
*ErrorPos=-1;
*ErrorNr=-1;
} else {
DelTree(&wurzel);
*ErrorPos=AktPos;
*ErrorNr=ErrTyp;
}
return wurzel;
}
void DelTree(PTNODE *ptnode)
{
if (*ptnode!=NULL) {
DelTree(&((*ptnode)->LeftAst));
DelTree(&((*ptnode)->RightAst));
if (((*ptnode)->operator=='\0')) {
LocalFree((LOCALHANDLE) (*ptnode)->operand);
LocalFree((LOCALHANDLE)*ptnode);
*ptnode=NULL;
} else {
LocalFree((LOCALHANDLE)*ptnode);
*ptnode=NULL;
}
}
}
void nextchar(int start,char f[])
{
if (start > strlen(f)) aktchar='\0';
else {
do
(start)++;
while (!((f[start-1]!=' ') || (start>=strlen(f))));
if (start<=strlen(f)) {
AktPos=start;
aktchar=(f[AktPos-1] != ';' ? f[AktPos-1]:f[AktPos++]);
} else AktPos++;
}
}
void neuewurzel(PTNODE *wurzel,char f[])
{
PTNODE helpnode;
helpnode=(NODESTRUCT NEAR *)LocalAlloc (LPTR,sizeof(NODESTRUCT));
if (helpnode != NULL)
{
helpnode->LeftAst=*wurzel;
*wurzel=helpnode;
(*wurzel)->RightAst=NULL;
(*wurzel)->operator=aktchar;
(*wurzel)->operand=NULL;
nextchar(AktPos,f);
} else SendMessage(hWndglob,WM_DESTROY,0,0L);
}
void newnode(PTNODE *knoten)
{
*knoten=(NODESTRUCT NEAR *)LocalAlloc(LPTR,sizeof(NODESTRUCT));
if (*knoten != NULL)
{
(*knoten)->operator='\0';
(*knoten)->operand=NULL;
(*knoten)->RightAst=NULL;
(*knoten)->LeftAst=NULL;
} else SendMessage(hWndglob,WM_DESTROY,0,0L);
}
double Calc(PTNODE *ptnode)
{
double Wert;
int links,rechts;
switch ((*ptnode)->operator)
{
case '\0':
Wert=(*((*ptnode)->operand));
break;
case EQV:
case XOR:
case OR:
case AND:
rechts = (int) Calc(&((*ptnode)->RightAst));
case NOT:
links = (int) Calc(&((*ptnode)->LeftAst));
if((*ptnode)->operator == NOT)
Wert=(links == 0 ? 1.0: 0.0); else
if((*ptnode)->operator == AND)
Wert=(links != 0 && rechts != 0 ? 1.0: 0.0); else
if((*ptnode)->operator == OR)
Wert=(links != 0 || rechts != 0 ? 1.0: 0.0); else
if((*ptnode)->operator == XOR)
Wert=((links != 0 && rechts == 0) ||
(links == 0 && rechts != 0)) ? 1.0: 0.0; else
if((*ptnode)->operator == EQV)
Wert=((links == 0 && rechts == 0) ||
(links != 0 && rechts != 0)) ? 1.0: 0.0;
break;
case KLGL:
Wert=(Calc(&((*ptnode)->LeftAst))<=Calc(&((*ptnode)->RightAst)) ? 1.0: 0.0);
break;
case UNGL:
Wert=(Calc(&((*ptnode)->LeftAst))!=Calc(&((*ptnode)->RightAst)) ? 1.0: 0.0);
break;
case GRGL:
Wert=(Calc(&((*ptnode)->LeftAst))>=Calc(&((*ptnode)->RightAst)) ? 1.0: 0.0);
break;
case GL:
Wert=(Calc(&((*ptnode)->LeftAst))==Calc(&((*ptnode)->RightAst)) ? 1.0: 0.0);
break;
case KL:
Wert=(Calc(&((*ptnode)->LeftAst))<Calc(&((*ptnode)->RightAst)) ? 1.0: 0.0);
break;
case GR:
Wert=(Calc(&((*ptnode)->LeftAst))>Calc(&((*ptnode)->RightAst)) ? 1.0: 0.0);
break;
case '+':
Wert=(Calc(&((*ptnode)->LeftAst))+Calc(&((*ptnode)->RightAst)));
break;
case '-':
Wert=(Calc(&((*ptnode)->LeftAst))-Calc(&((*ptnode)->RightAst)));
break;
case '*':
Wert=(Calc(&((*ptnode)->LeftAst))*Calc(&((*ptnode)->RightAst)));
break;
case '/':
if(Calc(&((*ptnode)->RightAst)) == 0.0)
{
Wert = Calc(&((*ptnode)->RightAst));
PRINTF("# DIVIDE BY ZERO #");
break;
}
else
Wert=(Calc(&((*ptnode)->LeftAst))/Calc(&((*ptnode)->RightAst)));
break;
case '^':
Wert=(pow(Calc(&((*ptnode)->LeftAst)),Calc(&((*ptnode)->RightAst))));
break;
case Ln:
Wert=(log(Calc(&((*ptnode)->LeftAst))));
break;
case Log:
Wert=(log10(Calc(&((*ptnode)->LeftAst))));
break;
case Exponent:
Wert=(exp(Calc(&((*ptnode)->LeftAst))));
break;
case Sinus:
Wert=(sin(Calc(&((*ptnode)->LeftAst))));
break;
case Cosinus:
Wert=(cos(Calc(&((*ptnode)->LeftAst))));
break;
case Tangens:
Wert=(tan(Calc(&((*ptnode)->LeftAst))));
break;
case ArcSin:
Wert=(asin(Calc(&((*ptnode)->LeftAst))));
break;
case ArcCos:
Wert=(acos(Calc(&((*ptnode)->LeftAst))));
break;
case ArcTan:
Wert=(atan(Calc(&((*ptnode)->LeftAst))));
break;
case SinHyp:
Wert=(sinh(Calc(&((*ptnode)->LeftAst))));
break;
case CosHyp:
Wert=(cosh(Calc(&((*ptnode)->LeftAst))));
break;
case TanHyp:
Wert=(tanh(Calc(&((*ptnode)->LeftAst))));
break;
case Sqrt:
Wert=(sqrt(Calc(&((*ptnode)->LeftAst))));
break;
case Frac:
Wert=(double)((double)frac(Calc(&((*ptnode)->LeftAst))));
break;
case Absolut:
Wert=(double)((double)fabs(Calc(&((*ptnode)->LeftAst))));
break;
case Cotangens:
Wert=(cot(Calc(&((*ptnode)->LeftAst))));
break;
case ArcCot:
Wert=(arccot(Calc(&((*ptnode)->LeftAst))));
break;
case ArcTanHyp:
Wert=(arctanh(Calc(&((*ptnode)->LeftAst))));
break;
case SIGN:
Wert=(-Calc(&((*ptnode)->LeftAst)));
break;
}
return Wert;
}
void getnumber(char f[],int *posi,char dbStr[])
{
int LenF;
char *fhelp;
LenF = strlen(f);
fhelp = dbStr;
while(*posi <= LenF && f[*posi] > '/' && f[*posi] < ':')
{
*fhelp++ = f[*posi];
*posi += 1;
}
while(*posi <= LenF && f[*posi] == '.')
{
*fhelp++ = f[*posi];
*posi += 1;
}
while(*posi <= LenF && f[*posi] > '/' && f[*posi] < ':')
{
*fhelp++ = f[*posi];
*posi += 1;
}
while(*posi <= LenF && (f[*posi] == 'e' || f[*posi] == 'E'))
{
if (f[*posi] == 'e') f[*posi] = 'E';
*fhelp++ = f[*posi];
*posi += 1;
if (*posi <= LenF && (f[*posi] == '+' || f[*posi] == '-'))
{
*fhelp++ = f[*posi];
*posi += 1;
}
while(*posi <= LenF && f[*posi] > '/' && f[*posi] < ':')
{
*fhelp++ = f[*posi];
*posi += 1;
}
}
}
void PosVar(char fkt[],unsigned char name[])
{
int count = 0;
AktPos--;
while ((isalpha (fkt[AktPos]) || isdigit (fkt[AktPos])) && (count < NAMLEN))
name[count++] = fkt[AktPos++];
name[count] = '\0';
}
BOOL LogicAusdruck(char f[],unsigned char *token)
{
*token='\0';
if (!(memicmp("AND",&f[AktPos-1],3))) *token=AND;
else if(!(memicmp("XOR",&f[AktPos-1],3))) *token=XOR;
else if(!(memicmp("OR",&f[AktPos-1],2))) *token=OR;
else if(!(memicmp("EQV",&f[AktPos-1],3))) *token=EQV;
return (*token ? TRUE : FALSE);
}
BOOL unaerefunktion(char f[],unsigned char *token)
{
*token='\0';
if (!(memicmp("ln",&f[AktPos-1],2))) *token=Ln;
else if(!(memicmp("sinh",&f[AktPos-1],4))) *token=SinHyp;
else if(!(memicmp("cosh",&f[AktPos-1],4))) *token=CosHyp;
else if(!(memicmp("tanh",&f[AktPos-1],4))) *token=TanHyp;
else if(!(memicmp("sqrt",&f[AktPos-1],4))) *token=Sqrt;
else if(!(memicmp("frac",&f[AktPos-1],4))) *token=Frac;
else if(!(memicmp("log",&f[AktPos-1],3))) *token=Log;
else if(!(memicmp("exp",&f[AktPos-1],3))) *token=Exponent;
else if(!(memicmp("sin",&f[AktPos-1],3))) *token=Sinus;
else if(!(memicmp("cos",&f[AktPos-1],3))) *token=Cosinus;
else if(!(memicmp("tan",&f[AktPos-1],3))) *token=Tangens;
else if(!(memicmp("abs",&f[AktPos-1],3))) *token=Absolut;
else if(!(memicmp("cot",&f[AktPos-1],3))) *token=Cotangens;
else if(!(memicmp("NOT",&f[AktPos-1],3))) *token=NOT;
else if(!(memicmp("arctanh",&f[AktPos-1],7))) *token=ArcTanHyp;
else if(!(memicmp("arcsin",&f[AktPos-1],6))) *token=ArcSin;
else if(!(memicmp("arccos",&f[AktPos-1],6))) *token=ArcCos;
else if(!(memicmp("arctan",&f[AktPos-1],6))) *token=ArcTan;
else if(!(memicmp("arccot",&f[AktPos-1],6))) *token=ArcCot;
switch (*token)
{
case ArcTanHyp:
AktPos++;
case ArcSin:
case ArcCos:
case ArcTan:
case ArcCot:
AktPos++;
AktPos++;
case SinHyp:
case CosHyp:
case TanHyp:
case Sqrt:
case Frac:
AktPos++;
case Log:
case Exponent:
case Sinus:
case Cosinus:
case Tangens:
case Absolut:
case Cotangens:
case NOT:
AktPos++;
case Ln:
AktPos++;
nextchar(AktPos,f);
break;
}
return (*token ? TRUE : FALSE);
}
PTNODE faktor(char f[])
{
PTNODE knoten;
VAR *Variable;
int valid,posi;
unsigned char token;
char DoubleStr[30];
knoten=NULL;
if (aktchar=='(') {
nextchar(AktPos,f);
knoten=verknuepf(f);
if ((aktchar!=')') && (!TreeError))
{
TreeError=TRUE;
ErrTyp=0;
}
if (!TreeError) nextchar(AktPos,f);
}
else if (unaerefunktion(f,&token))
{
if (aktchar!='(')
{
TreeError=TRUE;
ErrTyp=1;
} else
{
newnode(&knoten);
knoten->operator=token;
nextchar(AktPos,f);
knoten->LeftAst=verknuepf(f);
}
if ((aktchar!=')') && (!TreeError))
{
TreeError=TRUE;
ErrTyp=0;
}
if (!TreeError) nextchar(AktPos,f);
} else if(isalpha(aktchar) && !LogicAusdruck(f,&token)) {
newnode(&knoten);
knoten->operand=(double NEAR *)LocalAlloc (LPTR,sizeof(double));
if (knoten->operand== NULL)
{
TreeError=TRUE;
ErrTyp=6;
} else
{
PosVar(f,DoubleStr);
if(!(strcmp("e",DoubleStr))) *(knoten->operand)= e;
else
if(!(strcmp("pi",DoubleStr))) *(knoten->operand)= pi;
else
if(!(strcmp("rnd",DoubleStr))) *(knoten->operand)= random();
else if ((Variable = IsVariable (DoubleStr)) != NULL)
{
if(Variable->VarType == FLONUM)
*(knoten->operand)= Variable->VarWert.variable.Flotype;
else {
TreeError=TRUE;
ErrTyp=7;
}
}
else {
TreeError=TRUE;
ErrTyp=5;
}
}
if (!TreeError) nextchar(AktPos,f);
} else if ((aktchar>='0') && (aktchar<='9') || (aktchar=='.')) {
newnode(&knoten);
knoten->operand=(double NEAR *)LocalAlloc (LPTR,sizeof(double));
if (knoten->operand== NULL)
{
TreeError=TRUE;
ErrTyp=6;
}
else
{
posi=AktPos-1;
memset(DoubleStr,'\0',29);
getnumber(f,&posi,DoubleStr);
*(knoten->operand) = atof(DoubleStr);
AktPos=posi;
nextchar(AktPos,f);
}
} else {
TreeError=TRUE;
if ((aktchar==' ') || (AktPos==strlen(f)+1))
ErrTyp=3;
else ErrTyp=4;
}
return knoten;
}
PTNODE vorzfaktor(char f[])
{
PTNODE wurzel;
wurzel=NULL;
if ((aktchar=='-')) {
newnode(&wurzel);
wurzel->operator=SIGN;
nextchar(AktPos,f);
wurzel->LeftAst=faktor(f);
} else if (aktchar=='+') {
nextchar(AktPos,f);
wurzel=faktor(f);
} else {
wurzel=faktor(f);
}
return wurzel;
}
PTNODE potenz(char f[])
{
PTNODE wurzel;
wurzel=NULL;
wurzel=vorzfaktor(f);
while ((aktchar=='^') && (!TreeError)) {
neuewurzel(&wurzel,f);
wurzel->RightAst=vorzfaktor(f);
}
return wurzel;
}
PTNODE produkt(char f[])
{
PTNODE wurzel;
wurzel=NULL;
wurzel=potenz(f);
while ((aktchar=='*' || aktchar=='/') && !TreeError) {
neuewurzel(&wurzel,f);
wurzel->RightAst=potenz(f);
}
return wurzel;
}
PTNODE summe(char f[])
{
PTNODE wurzel;
wurzel=NULL;
wurzel=produkt(f);
while ((aktchar=='+' || aktchar=='-') && !TreeError) {
neuewurzel(&wurzel,f);
wurzel->RightAst=produkt(f);
}
return wurzel;
}
PTNODE vergleich(char f[])
{
PTNODE wurzel;
wurzel=NULL;
wurzel=summe(f);
while ((aktchar==KL || aktchar==GR || aktchar==GL) && !TreeError)
{
if(aktchar==KL && f[AktPos] == GL) aktchar=KLGL;
else
if(aktchar==KL && f[AktPos] == GR) aktchar=UNGL;
else
if(aktchar==GR && f[AktPos] == GL) aktchar=GRGL;
if(aktchar==KLGL || aktchar==UNGL || aktchar==GRGL) AktPos++;
neuewurzel(&wurzel,f);
wurzel->RightAst=summe(f);
}
return wurzel;
}
PTNODE verknuepf(char f[])
{
PTNODE wurzel;
unsigned char token;
wurzel=NULL;
wurzel=vergleich(f);
while (LogicAusdruck(f,&token) && !TreeError)
{
aktchar=token;
AktPos++;
if(aktchar!=OR) AktPos++;
neuewurzel(&wurzel,f);
wurzel->RightAst=vergleich(f);
}
return wurzel;
}
double cot(double x)
{
double r_cot;
if (frac(x/PI_HALBE)!=0) r_cot = 1 / tan(x);
return r_cot;
}
double arccot(double x)
{
double r_arccot;
r_arccot=PI_HALBE-atan(x);
return r_arccot;
}
double fsqr(double x)
{
return x*x;
}
double frac(double x)
{
double d;
return modf(x,&d);
}
double arctanh(double x)
{
double r_arctanh;
if (fabs(x)<1.0) r_arctanh=0.5*log((1.0+x)/(1.0-x));
return r_arctanh;
}
float ran1(void)
{
static long int a = 100001;
a = (a*125) % 2796203;
return((float) a/2796203);
}
float ran2(void)
{
static long int a = 1;
a = (a*32719+3) % 32749;
return((float) a/32749);
}
float ran3(void)
{
static long int a = 203;
a = (a*10001+3) % 1717;
return((float) a/1717);
}
float random()
{
float f;
f=ran3();
if(f>.5) return ran1();
else return ran2();
}
void LiesDaten(void)
{
BYTE *Text;
long cnt;
char *FName;
if ((FName = GetFileName()) != NULL)
fio = OpenFile((LPSTR)FName,(LPOFSTRUCT)&fileInfo,OF_READ);
else return;
if(fio == -1)
{
PRINTF("# ERROR OPEN #");
return;
}
if((cnt = filelength(fio)) == -1)
{
PRINTF("# ERROR READ #");
return;
}
if(cnt > 20000) return;
if ((hEditText = LocalAlloc(LMEM_MOVEABLE | LMEM_ZEROINIT,(unsigned) cnt + 3 )) == NULL)
{
PRINTF("# ERROR ALLOCATE #");
return;
}
if (read (fio,Text = LocalLock(hEditText),(unsigned) cnt) != (unsigned) cnt)
{
LocalUnlock(hEditText);
PRINTF("# ERROR LOCK #");
return;
}
bText=TRUE;
LocalUnlock(hEditText);
SendMessage(hWndEdit,EM_SETHANDLE,(WORD) hEditText,0L);
if(close(fio)==-1) return;
}
void SaveDaten()
{
int cnt;
char *FName;
if ((FName = GetFileName()) != NULL)
fio = OpenFile( (LPSTR) FName,(LPOFSTRUCT) &fileInfo, OF_CREATE | OF_WRITE);
else return;
if (fio == -1)
return;
if (((cnt =(unsigned) SendMessage(hWndEdit,WM_GETTEXTLENGTH,0,0l)) > 0) &&
((hEditText = (HANDLE) SendMessage(hWndEdit,EM_GETHANDLE,0,0l)) != NULL))
{
if (write (fio, LocalLock(hEditText), cnt) != cnt)
{
LocalUnlock(hEditText);
return;
}
LocalUnlock(hEditText);
}
if (close(fio) == -1 ) return;
}