home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / spezial / 20 / win_txl / formel.c next >
Encoding:
C/C++ Source or Header  |  1991-03-12  |  18.1 KB  |  704 lines

  1. /************************************************************************
  2. *                .......................................                *
  3. *                .                                     .                *
  4. *                .       TOOLBOX - INTERPRETER         .                *
  5. *                . TESTPROGRAMM FÜR WINDOWS-FUNKTIONEN .                *
  6. *                .             FORMEL.C                .                *
  7. *                .    M.Beising & K.Bauer & TOOLBOX    .                *
  8. *                .......................................                *
  9. *************************************************************************/
  10.  
  11. #include <windows.h>
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include <ctype.h>
  16. #include <math.h>
  17. #include "txl.h"
  18.  
  19. PTNODE CreateTree(char Fktzeile[],int *ErrorPos,int *ErrorNr);
  20. PTNODE faktor(char f[]);
  21. PTNODE vorzfaktor(char f[]);
  22. PTNODE potenz(char f[]);
  23. PTNODE produkt(char f[]);
  24. PTNODE summe(char f[]);
  25. PTNODE vergleich(char f[]);
  26. PTNODE verknuepf(char f[]);
  27. void DelTree(PTNODE *ptnode);
  28. void nextchar(int start,char f[]);
  29. void neuewurzel(PTNODE *wurzel,char f[]);
  30. void newnode(PTNODE *knoten);
  31. BOOL unaerefunktion(char f[],unsigned char *token);
  32. void getnumber(char f[],int *posi,char fhelp[30]);
  33. double Calc(PTNODE *ptnode);
  34. double arctanh(double x);
  35. double arccot(double x);
  36. double cot(double x);
  37. double frac(double f);
  38. long round(double x);
  39. float ran1(void);
  40. float ran2(void);
  41. float ran3(void);
  42. float random();
  43. void LiesDaten(void);
  44. void SaveDaten(void);
  45. extern char   *GetFileName (void);
  46.  
  47. extern int  AktPos,ErrTyp,ErrPos,ErrNr,fio;
  48. extern BOOL TreeError;
  49. extern HWND hWndglob,hWndEdit;
  50. extern char FileName[FNAMLEN];
  51. extern HANDLE hEditText;
  52. extern OFSTRUCT fileInfo;
  53. extern BOOL bText;
  54. unsigned char aktchar;
  55.  
  56. PTNODE CreateTree(char Fktzeile[],int *ErrorPos,int *ErrorNr)
  57. {
  58.   PTNODE wurzel;
  59.   AktPos=0;
  60.   nextchar(AktPos,Fktzeile);
  61.   TreeError=FALSE;
  62.   wurzel=NULL;
  63.   wurzel=verknuepf(Fktzeile);
  64.   if ((AktPos<=strlen(Fktzeile)) && (Fktzeile[AktPos-1]!=' ') && (!TreeError)) {
  65.     TreeError=TRUE;
  66.     ErrTyp=4;
  67.   }
  68.   if (!TreeError) {
  69.     *ErrorPos=-1;
  70.     *ErrorNr=-1;
  71.   } else {
  72.     DelTree(&wurzel);
  73.     *ErrorPos=AktPos;
  74.     *ErrorNr=ErrTyp;
  75.   }
  76.   return wurzel;
  77. }
  78.  
  79.  
  80. void DelTree(PTNODE *ptnode)
  81. {
  82.   if (*ptnode!=NULL) {
  83.     DelTree(&((*ptnode)->LeftAst));
  84.     DelTree(&((*ptnode)->RightAst));
  85.     if (((*ptnode)->operator=='\0')) {
  86.       LocalFree((LOCALHANDLE) (*ptnode)->operand);
  87.       LocalFree((LOCALHANDLE)*ptnode);
  88.       *ptnode=NULL;
  89.     } else {
  90.       LocalFree((LOCALHANDLE)*ptnode);
  91.       *ptnode=NULL;
  92.     }
  93.   }
  94. }
  95.  
  96. void nextchar(int start,char f[])
  97. {
  98.   if (start > strlen(f)) aktchar='\0';
  99.   else {
  100.     do
  101.       (start)++;
  102.     while (!((f[start-1]!=' ') || (start>=strlen(f))));
  103.     if (start<=strlen(f)) {
  104.       AktPos=start;
  105.       aktchar=(f[AktPos-1] != ';' ? f[AktPos-1]:f[AktPos++]);
  106.     } else AktPos++;
  107.   }
  108. }
  109.  
  110. void neuewurzel(PTNODE *wurzel,char f[])
  111. {
  112.   PTNODE helpnode;
  113.   helpnode=(NODESTRUCT NEAR *)LocalAlloc (LPTR,sizeof(NODESTRUCT));
  114.   if (helpnode != NULL)
  115.    {
  116.     helpnode->LeftAst=*wurzel;
  117.     *wurzel=helpnode;
  118.     (*wurzel)->RightAst=NULL;
  119.     (*wurzel)->operator=aktchar;
  120.     (*wurzel)->operand=NULL;
  121.     nextchar(AktPos,f);
  122.    } else SendMessage(hWndglob,WM_DESTROY,0,0L);
  123.  
  124. }
  125.  
  126. void newnode(PTNODE *knoten)
  127. {
  128.   *knoten=(NODESTRUCT NEAR *)LocalAlloc(LPTR,sizeof(NODESTRUCT));
  129.   if (*knoten != NULL)
  130.    {
  131.     (*knoten)->operator='\0';
  132.     (*knoten)->operand=NULL;
  133.     (*knoten)->RightAst=NULL;
  134.     (*knoten)->LeftAst=NULL;
  135.    } else SendMessage(hWndglob,WM_DESTROY,0,0L);
  136. }
  137.  
  138. double Calc(PTNODE *ptnode)
  139. {
  140.   double Wert;
  141.   int links,rechts;
  142.  switch ((*ptnode)->operator)
  143.    {
  144.     case '\0':
  145.       Wert=(*((*ptnode)->operand));
  146.       break;
  147.     case EQV:
  148.     case XOR:
  149.     case OR:
  150.     case AND:
  151.       rechts = (int) Calc(&((*ptnode)->RightAst));
  152.     case NOT:
  153.       links  = (int) Calc(&((*ptnode)->LeftAst));
  154.     if((*ptnode)->operator == NOT)
  155.                 Wert=(links == 0 ? 1.0: 0.0); else
  156.     if((*ptnode)->operator == AND)
  157.                 Wert=(links != 0 && rechts != 0 ? 1.0: 0.0); else
  158.     if((*ptnode)->operator == OR)
  159.                 Wert=(links != 0 || rechts != 0 ? 1.0: 0.0); else
  160.     if((*ptnode)->operator == XOR)
  161.                 Wert=((links != 0 && rechts == 0) ||
  162.                         (links == 0 && rechts != 0)) ? 1.0: 0.0; else
  163.     if((*ptnode)->operator == EQV)
  164.                 Wert=((links == 0 && rechts == 0) ||
  165.                         (links != 0 && rechts != 0)) ? 1.0: 0.0;
  166.       break;
  167.     case KLGL:
  168.       Wert=(Calc(&((*ptnode)->LeftAst))<=Calc(&((*ptnode)->RightAst)) ? 1.0: 0.0);
  169.       break;
  170.     case UNGL:
  171.       Wert=(Calc(&((*ptnode)->LeftAst))!=Calc(&((*ptnode)->RightAst)) ? 1.0: 0.0);
  172.       break;
  173.     case GRGL:
  174.       Wert=(Calc(&((*ptnode)->LeftAst))>=Calc(&((*ptnode)->RightAst)) ? 1.0: 0.0);
  175.       break;
  176.     case GL:
  177.       Wert=(Calc(&((*ptnode)->LeftAst))==Calc(&((*ptnode)->RightAst)) ? 1.0: 0.0);
  178.       break;
  179.     case KL:
  180.       Wert=(Calc(&((*ptnode)->LeftAst))<Calc(&((*ptnode)->RightAst)) ? 1.0: 0.0);
  181.       break;
  182.     case GR:
  183.       Wert=(Calc(&((*ptnode)->LeftAst))>Calc(&((*ptnode)->RightAst)) ? 1.0: 0.0);
  184.       break;
  185.     case '+':
  186.       Wert=(Calc(&((*ptnode)->LeftAst))+Calc(&((*ptnode)->RightAst)));
  187.       break;
  188.     case '-':
  189.       Wert=(Calc(&((*ptnode)->LeftAst))-Calc(&((*ptnode)->RightAst)));
  190.       break;
  191.     case '*':
  192.       Wert=(Calc(&((*ptnode)->LeftAst))*Calc(&((*ptnode)->RightAst)));
  193.       break;
  194.     case '/':
  195.       if(Calc(&((*ptnode)->RightAst)) == 0.0)
  196.           {
  197.            Wert = Calc(&((*ptnode)->RightAst));
  198.            PRINTF("# DIVIDE BY ZERO #");
  199.            break;
  200.           }
  201.        else
  202.            Wert=(Calc(&((*ptnode)->LeftAst))/Calc(&((*ptnode)->RightAst)));
  203.       break;
  204.     case '^':
  205.        Wert=(pow(Calc(&((*ptnode)->LeftAst)),Calc(&((*ptnode)->RightAst))));
  206.       break;
  207.     case Ln:
  208.       Wert=(log(Calc(&((*ptnode)->LeftAst))));
  209.       break;
  210.     case Log:
  211.       Wert=(log10(Calc(&((*ptnode)->LeftAst))));
  212.       break;
  213.     case Exponent:
  214.       Wert=(exp(Calc(&((*ptnode)->LeftAst))));
  215.       break;
  216.     case Sinus:
  217.       Wert=(sin(Calc(&((*ptnode)->LeftAst))));
  218.       break;
  219.     case Cosinus:
  220.       Wert=(cos(Calc(&((*ptnode)->LeftAst))));
  221.       break;
  222.     case Tangens:
  223.       Wert=(tan(Calc(&((*ptnode)->LeftAst))));
  224.       break;
  225.     case ArcSin:
  226.       Wert=(asin(Calc(&((*ptnode)->LeftAst))));
  227.       break;
  228.     case ArcCos:
  229.       Wert=(acos(Calc(&((*ptnode)->LeftAst))));
  230.       break;
  231.     case ArcTan:
  232.       Wert=(atan(Calc(&((*ptnode)->LeftAst))));
  233.       break;
  234.     case SinHyp:
  235.       Wert=(sinh(Calc(&((*ptnode)->LeftAst))));
  236.       break;
  237.     case CosHyp:
  238.       Wert=(cosh(Calc(&((*ptnode)->LeftAst))));
  239.       break;
  240.     case TanHyp:
  241.       Wert=(tanh(Calc(&((*ptnode)->LeftAst))));
  242.       break;
  243.     case Sqrt:
  244.       Wert=(sqrt(Calc(&((*ptnode)->LeftAst))));
  245.       break;
  246.     case Frac:
  247.       Wert=(double)((double)frac(Calc(&((*ptnode)->LeftAst))));
  248.       break;
  249.     case Round:
  250.       Wert=(double)((double)round(Calc(&((*ptnode)->LeftAst))));
  251.       break;
  252.     case Absolut:
  253.       Wert=(double)((double)fabs(Calc(&((*ptnode)->LeftAst))));
  254.       break;
  255.     case Cotangens:
  256.       Wert=(cot(Calc(&((*ptnode)->LeftAst))));
  257.       break;
  258.     case ArcCot:
  259.       Wert=(arccot(Calc(&((*ptnode)->LeftAst))));
  260.       break;
  261.     case ArcTanHyp:
  262.       Wert=(arctanh(Calc(&((*ptnode)->LeftAst))));
  263.       break;
  264.     case SIGN:
  265.       Wert=(-Calc(&((*ptnode)->LeftAst)));
  266.       break;
  267.    }
  268.    return Wert;
  269. }
  270.  
  271. void getnumber(char f[],int *posi,char dbStr[])
  272. {
  273.  int   LenF;
  274.  char  *fhelp;
  275.  LenF = strlen(f);
  276.  fhelp = dbStr;
  277.  while(*posi <= LenF && f[*posi] > '/' && f[*posi] < ':')
  278.        {
  279.           *fhelp++ = f[*posi];
  280.           *posi += 1;
  281.        }
  282.  while(*posi <= LenF && f[*posi] == '.')
  283.        {
  284.           *fhelp++ = f[*posi];
  285.           *posi += 1;
  286.        }
  287.  while(*posi <= LenF && f[*posi] > '/' && f[*posi] < ':')
  288.        {
  289.           *fhelp++ = f[*posi];
  290.           *posi += 1;
  291.        }
  292.  while(*posi <= LenF && (f[*posi] == 'e' || f[*posi] == 'E'))
  293.        {
  294.           if (f[*posi] == 'e') f[*posi] = 'E';
  295.           *fhelp++ = f[*posi];
  296.           *posi += 1;
  297.           if (*posi <= LenF && (f[*posi] == '+' || f[*posi] == '-'))
  298.           {
  299.            *fhelp++ = f[*posi];
  300.            *posi += 1;
  301.           }
  302.  while(*posi <= LenF && f[*posi] > '/' && f[*posi] < ':')
  303.        {
  304.           *fhelp++ = f[*posi];
  305.           *posi += 1;
  306.        }
  307.        }
  308. }
  309.  
  310. void PosVar(char fkt[],unsigned char name[])
  311. {
  312.  int count = 0;
  313.  AktPos--;
  314.  while ((isalpha (fkt[AktPos]) || isdigit (fkt[AktPos])) && (count < NAMLEN))
  315.     name[count++] = fkt[AktPos++];
  316.     name[count] = '\0';
  317. }
  318.  
  319. BOOL LogicAusdruck(char f[],unsigned char *token)
  320. {
  321.   *token='\0';
  322.   if (!(memicmp("AND",&f[AktPos-1],3)))        *token=AND;
  323.   else if(!(memicmp("XOR",&f[AktPos-1],3)))    *token=XOR;
  324.   else if(!(memicmp("OR",&f[AktPos-1],2)))     *token=OR;
  325.   else if(!(memicmp("EQV",&f[AktPos-1],3)))    *token=EQV;
  326.   return (*token ? TRUE : FALSE);
  327. }
  328.  
  329. BOOL unaerefunktion(char f[],unsigned char *token)
  330. {
  331.   *token='\0';
  332.   if (!(memicmp("ln",&f[AktPos-1],2)))          *token=Ln;
  333.   else if(!(memicmp("sinh",&f[AktPos-1],4)))    *token=SinHyp;
  334.   else if(!(memicmp("cosh",&f[AktPos-1],4)))    *token=CosHyp;
  335.   else if(!(memicmp("tanh",&f[AktPos-1],4)))    *token=TanHyp;
  336.   else if(!(memicmp("sqrt",&f[AktPos-1],4)))    *token=Sqrt;
  337.   else if(!(memicmp("frac",&f[AktPos-1],4)))    *token=Frac;
  338.   else if(!(memicmp("round",&f[AktPos-1],4)))   *token=Round;
  339.   else if(!(memicmp("log",&f[AktPos-1],3)))     *token=Log;
  340.   else if(!(memicmp("exp",&f[AktPos-1],3)))     *token=Exponent;
  341.   else if(!(memicmp("sin",&f[AktPos-1],3)))     *token=Sinus;
  342.   else if(!(memicmp("cos",&f[AktPos-1],3)))     *token=Cosinus;
  343.   else if(!(memicmp("tan",&f[AktPos-1],3)))     *token=Tangens;
  344.   else if(!(memicmp("abs",&f[AktPos-1],3)))     *token=Absolut;
  345.   else if(!(memicmp("cot",&f[AktPos-1],3)))     *token=Cotangens;
  346.   else if(!(memicmp("NOT",&f[AktPos-1],3)))     *token=NOT;
  347.   else if(!(memicmp("arctanh",&f[AktPos-1],7))) *token=ArcTanHyp;
  348.   else if(!(memicmp("arcsin",&f[AktPos-1],6)))  *token=ArcSin;
  349.   else if(!(memicmp("arccos",&f[AktPos-1],6)))  *token=ArcCos;
  350.   else if(!(memicmp("arctan",&f[AktPos-1],6)))  *token=ArcTan;
  351.   else if(!(memicmp("arccot",&f[AktPos-1],6)))  *token=ArcCot;
  352.  
  353.    switch (*token)
  354.           {
  355.            case ArcTanHyp:
  356.                 AktPos++;
  357.            case ArcSin:
  358.            case ArcCos:
  359.            case ArcTan:
  360.            case ArcCot:
  361.                 AktPos++;
  362.            case Round:
  363.                 AktPos++;
  364.            case SinHyp:
  365.            case CosHyp:
  366.            case TanHyp:
  367.            case Sqrt:
  368.            case Frac:
  369.                 AktPos++;
  370.            case Log:
  371.            case Exponent:
  372.            case Sinus:
  373.            case Cosinus:
  374.            case Tangens:
  375.            case Absolut:
  376.            case Cotangens:
  377.            case NOT:
  378.                 AktPos++;
  379.            case Ln:
  380.                 AktPos++;
  381.                 nextchar(AktPos,f);
  382.       break;
  383.   }
  384.   return (*token ? TRUE : FALSE);
  385. }
  386.  
  387. PTNODE faktor(char f[])
  388. {
  389. PTNODE knoten;
  390. VAR *Variable;
  391.   int   valid,posi;
  392. unsigned char token;
  393.   char DoubleStr[30];
  394.   knoten=NULL;
  395.    if (aktchar=='(') {
  396.        nextchar(AktPos,f);
  397.        knoten=verknuepf(f);
  398.    if ((aktchar!=')') && (!TreeError))
  399.       {
  400.        TreeError=TRUE;
  401.        ErrTyp=0;
  402.       }
  403.      if (!TreeError) nextchar(AktPos,f);
  404.     }
  405.     else if (unaerefunktion(f,&token))
  406.    {
  407.      if (aktchar!='(')
  408.      {
  409.        TreeError=TRUE;
  410.        ErrTyp=1;
  411.      } else
  412.       {
  413.        newnode(&knoten);
  414.        knoten->operator=token;
  415.        nextchar(AktPos,f);
  416.        knoten->LeftAst=verknuepf(f);
  417.       }
  418.     if ((aktchar!=')') && (!TreeError))
  419.       {
  420.        TreeError=TRUE;
  421.        ErrTyp=0;
  422.       }
  423.     if (!TreeError) nextchar(AktPos,f);
  424.   } else if(isalpha(aktchar) && !LogicAusdruck(f,&token)) {
  425.           newnode(&knoten);
  426.        knoten->operand=(double NEAR *)LocalAlloc (LPTR,sizeof(double));
  427.      if (knoten->operand== NULL)
  428.            {
  429.              TreeError=TRUE;
  430.               ErrTyp=6;
  431.            } else
  432.             {
  433.              PosVar(f,DoubleStr);
  434.              if(!(strcmp("e",DoubleStr))) *(knoten->operand)= e;
  435.               else
  436.               if(!(strcmp("pi",DoubleStr))) *(knoten->operand)= pi;
  437.                else
  438.                  if(!(strcmp("rnd",DoubleStr))) *(knoten->operand)= random();
  439.                 else if ((Variable = IsVariable (DoubleStr)) != NULL)
  440.                     {
  441.                       if(Variable->VarType == FLONUM)
  442.                         *(knoten->operand)= Variable->VarWert.variable.Flotype;
  443.                        else  {
  444.                                  TreeError=TRUE;
  445.                                  ErrTyp=7;
  446.                                 }
  447.                     }
  448.                      else  {
  449.                               TreeError=TRUE;
  450.                               ErrTyp=5;
  451.                            }
  452.             }
  453.            if (!TreeError) nextchar(AktPos,f);
  454.   } else if ((aktchar>='0') && (aktchar<='9') || (aktchar=='.')) {
  455.     newnode(&knoten);
  456.     knoten->operand=(double NEAR *)LocalAlloc (LPTR,sizeof(double));
  457.      if (knoten->operand== NULL)
  458.            {
  459.              TreeError=TRUE;
  460.              ErrTyp=6;
  461.            }
  462.        else
  463.            {
  464.              posi=AktPos-1;
  465.              memset(DoubleStr,'\0',29);
  466.              getnumber(f,&posi,DoubleStr);
  467.              *(knoten->operand) = atof(DoubleStr);
  468.              AktPos=posi;
  469.              nextchar(AktPos,f);
  470.            }
  471.   } else {
  472.     TreeError=TRUE;
  473.     if ((aktchar==' ') || (AktPos==strlen(f)+1))
  474.       ErrTyp=3;
  475.     else ErrTyp=4;
  476.   }
  477.   return knoten;
  478. }
  479.  
  480.  
  481. PTNODE vorzfaktor(char f[])
  482. {
  483.   PTNODE wurzel;
  484.   wurzel=NULL;
  485.   if ((aktchar=='-')) {
  486.     newnode(&wurzel);
  487.     wurzel->operator=SIGN;
  488.     nextchar(AktPos,f);
  489.     wurzel->LeftAst=faktor(f);
  490.   } else if (aktchar=='+') {
  491.     nextchar(AktPos,f);
  492.     wurzel=faktor(f);
  493.   } else {
  494.     wurzel=faktor(f);
  495.   }
  496.   return wurzel;
  497. }
  498.  
  499. PTNODE potenz(char f[])
  500. {
  501.   PTNODE wurzel;
  502.   wurzel=NULL;
  503.   wurzel=vorzfaktor(f);
  504.   while ((aktchar=='^') && (!TreeError)) {
  505.     neuewurzel(&wurzel,f);
  506.     wurzel->RightAst=vorzfaktor(f);
  507.   }
  508.   return wurzel;
  509. }
  510.  
  511. PTNODE produkt(char f[])
  512. {
  513.   PTNODE wurzel;
  514.   wurzel=NULL;
  515.   wurzel=potenz(f);
  516.   while ((aktchar=='*' || aktchar=='/') && !TreeError) {
  517.     neuewurzel(&wurzel,f);
  518.     wurzel->RightAst=potenz(f);
  519.   }
  520.   return wurzel;
  521. }
  522. PTNODE summe(char f[])
  523. {
  524.   PTNODE wurzel;
  525.   wurzel=NULL;
  526.   wurzel=produkt(f);
  527.   while ((aktchar=='+' || aktchar=='-') && !TreeError) {
  528.     neuewurzel(&wurzel,f);
  529.     wurzel->RightAst=produkt(f);
  530.   }
  531.   return wurzel;
  532. }
  533. PTNODE vergleich(char f[])
  534. {
  535.   PTNODE wurzel;
  536.   wurzel=NULL;
  537.   wurzel=summe(f);
  538.  
  539. while ((aktchar==KL || aktchar==GR || aktchar==GL) && !TreeError)
  540.   {
  541.     if(aktchar==KL && f[AktPos] == GL) aktchar=KLGL;
  542.       else
  543.        if(aktchar==KL && f[AktPos] == GR) aktchar=UNGL;
  544.           else
  545.            if(aktchar==GR && f[AktPos] == GL) aktchar=GRGL;
  546.  
  547.           if(aktchar==KLGL || aktchar==UNGL || aktchar==GRGL) AktPos++;
  548.  
  549.     neuewurzel(&wurzel,f);
  550.     wurzel->RightAst=summe(f);
  551.   }
  552.   return wurzel;
  553. }
  554.  
  555. PTNODE verknuepf(char f[])
  556. {
  557.   PTNODE wurzel;
  558.   unsigned char token;
  559.   wurzel=NULL;
  560.   wurzel=vergleich(f);
  561.  
  562. while (LogicAusdruck(f,&token) && !TreeError)
  563.   {
  564.      aktchar=token;
  565.       AktPos++;
  566.      if(aktchar!=OR) AktPos++;
  567.     neuewurzel(&wurzel,f);
  568.     wurzel->RightAst=vergleich(f);
  569.   }
  570.   return wurzel;
  571. }
  572.  
  573. double cot(double x)
  574. {
  575.   double r_cot;
  576.  
  577.   if (frac(x/PI_HALBE)!=0) r_cot = 1 / tan(x);
  578.   return r_cot;
  579. }
  580.  
  581. double arccot(double x)
  582. {
  583.   double r_arccot;
  584.  
  585.   r_arccot=PI_HALBE-atan(x);
  586.   return r_arccot;
  587. }
  588.  
  589. long round(double x)
  590. {
  591.   return ((x>0.0)?(long int)(x+0.5):(long int)(x-0.5));
  592. }
  593.  
  594. double fsqr(double x)
  595. {
  596.   return x*x;
  597. }
  598.  
  599. double frac(double x)
  600. {
  601.   double d;
  602.   return modf(x,&d);
  603. }
  604.  
  605. double arctanh(double x)
  606. {
  607.   double r_arctanh;
  608.  
  609.   if (fabs(x)<1.0) r_arctanh=0.5*log((1.0+x)/(1.0-x));
  610.   return r_arctanh;
  611. }
  612.  
  613. float ran1(void)
  614. {
  615.  static long int a = 100001;
  616.  a = (a*125) % 2796203;
  617.  return((float) a/2796203);
  618.  
  619. }
  620. float ran2(void)
  621. {
  622.  static long int a = 1;
  623.  a = (a*32719+3) % 32749;
  624.  return((float) a/32749);
  625.  
  626. }
  627. float ran3(void)
  628. {
  629.  static long int a = 203;
  630.  a = (a*10001+3) % 1717;
  631.  return((float) a/1717);
  632. }
  633.  
  634. float random()
  635. {
  636. float f;
  637.  
  638.  f=ran3();
  639.  if(f>.5) return ran1();
  640.    else return ran2();
  641. }
  642.  
  643. void LiesDaten(void)
  644. {
  645. BYTE *Text;
  646. long cnt;
  647. char *FName;
  648.  
  649.  if ((FName = GetFileName()) != NULL)
  650.     fio = OpenFile((LPSTR)FName,(LPOFSTRUCT)&fileInfo,OF_READ);
  651.      else return;
  652.  
  653.    if(fio == -1)
  654.       {
  655.       PRINTF("# ERROR OPEN #");
  656.       return;
  657.       }
  658.  
  659.      if((cnt = filelength(fio)) == -1)
  660.       {
  661.       PRINTF("# ERROR READ #");
  662.       return;
  663.       }
  664.        if(cnt > 20000) return;
  665.   if ((hEditText = LocalAlloc(LMEM_MOVEABLE | LMEM_ZEROINIT,(unsigned) cnt + 3 )) == NULL)
  666.       {
  667.       PRINTF("# ERROR ALLOCATE #");
  668.       return;
  669.       }
  670.  if (read (fio,Text = LocalLock(hEditText),(unsigned) cnt) != (unsigned) cnt)
  671.    {
  672.     LocalUnlock(hEditText);
  673.     PRINTF("# ERROR LOCK #");
  674.     return;
  675.    }
  676.      bText=TRUE;
  677.   LocalUnlock(hEditText);
  678.   SendMessage(hWndEdit,EM_SETHANDLE,(WORD) hEditText,0L);
  679.  if(close(fio)==-1) return;
  680. }
  681.  
  682. void SaveDaten()
  683. {
  684. int cnt;
  685. char *FName;
  686. if ((FName = GetFileName()) != NULL)
  687.   fio = OpenFile( (LPSTR) FName,(LPOFSTRUCT) &fileInfo, OF_CREATE | OF_WRITE);
  688.    else return;
  689.   if (fio == -1)
  690.      return;
  691.  
  692.   if (((cnt =(unsigned) SendMessage(hWndEdit,WM_GETTEXTLENGTH,0,0l)) > 0) &&
  693.       ((hEditText = (HANDLE) SendMessage(hWndEdit,EM_GETHANDLE,0,0l)) != NULL))
  694.     {
  695.       if (write (fio, LocalLock(hEditText), cnt) != cnt)
  696.            {
  697.             LocalUnlock(hEditText);
  698.             return;
  699.            }
  700.       LocalUnlock(hEditText);
  701.     }
  702.   if (close(fio) == -1 ) return;
  703. }
  704.