home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PASCAL / PASWIZ13.ZIP / SOURCE.ZIP / EXTMATH.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1992-10-29  |  18.1 KB  |  743 lines

  1. {   +----------------------------------------------------------------------+
  2.     |                                                                      |
  3.     |        PasWiz  Copyright (c) 1990-1992  Thomas G. Hanlin III         |
  4.     |             3544 E. Southern Ave. #104,  Mesa, AZ 85204              |
  5.     |                                                                      |
  6.     |                     The Pascal Wizard's Library                      |
  7.     |                                                                      |
  8.     +----------------------------------------------------------------------+
  9.  
  10.  
  11.  
  12. Extended math:
  13.  
  14.    This unit contains procedures and functions that implement extensions to
  15.    Pascal's built-in math (new trig functions, et al) and an arithmetic
  16.    expression evaluator.  The latter is loosely based on EXPR.C from Dr.
  17.    Dobb's Journal, Sept 1985, p.25.
  18.  
  19. }
  20.  
  21. UNIT ExtMath;
  22.  
  23. INTERFACE
  24.  
  25. FUNCTION ArcCos (Number: Real): Real;
  26. FUNCTION ArcCosH (Number: Real): Real;
  27. FUNCTION ArcSin (Number: Real): Real;
  28. FUNCTION ArcSinH (Number: Real): Real;
  29. FUNCTION ArcTanH (Number: Real): Real;
  30. FUNCTION Ceil (Number: Real): Real;
  31. FUNCTION CosH (Number: Real): Real;
  32. FUNCTION Cot (Number: Real): Real;
  33. FUNCTION Csc (Number: Real): Real;
  34. FUNCTION Deg2Rad (Number: Real): Real;
  35. FUNCTION e: Real;
  36. FUNCTION Erf (Number: Real): Real;
  37. FUNCTION Fact (Number: Integer): Real;
  38. FUNCTION Floor (Number: Real): Real;
  39. FUNCTION Log (Number: Real): Real;
  40. FUNCTION Rad2Deg (Number: Real): Real;
  41. FUNCTION Raise (Number: Real; Power: Integer): Real;
  42. FUNCTION Sec (Number: Real): Real;
  43. FUNCTION SinH (Number: Real): Real;
  44. FUNCTION Tan (Number: Real): Real;
  45. FUNCTION TanH (Number: Real): Real;
  46.  
  47. PROCEDURE Evaluate (Expr: String; VAR Result: Real; VAR ErrCode: Integer);
  48.  
  49.  
  50.  
  51. { --------------------------------------------------------------------------- }
  52.  
  53.  
  54.  
  55. IMPLEMENTATION
  56.  
  57. { forward declarations for the Evaluate procedure }
  58. FUNCTION Eval (VAR Expr: String; VAR ErrCode: Integer): Real; FORWARD;
  59. FUNCTION Factor (VAR Expr: String; VAR ErrCode: Integer): Real; FORWARD;
  60. FUNCTION IsDigit (Expr: String): Boolean; FORWARD;
  61. FUNCTION Locase (Ch: Char): Char; FORWARD;
  62. FUNCTION ParensOk (Expr: String): Boolean; FORWARD;
  63. FUNCTION Term (VAR Expr: String; VAR ErrCode: Integer): Real; FORWARD;
  64. PROCEDURE AddParen (VAR Expr: String; Posn, WhichWay: Integer); FORWARD;
  65. PROCEDURE FixPrecedence (VAR Expr: String); FORWARD;
  66.  
  67.  
  68.  
  69. { ----- Ceiling ----- }
  70. FUNCTION Ceil (Number: Real): Real;
  71. BEGIN
  72.    IF Number = INT(Number) THEN
  73.       Ceil := Number
  74.    ELSE
  75.       Ceil := INT(Number) + 1.0;
  76. END;
  77.  
  78.  
  79.  
  80. { ----- Floor ----- }
  81. FUNCTION Floor (Number: Real): Real;
  82. BEGIN
  83.    IF Number = INT(Number) THEN
  84.       Floor := Number
  85.    ELSE
  86.       Floor := INT(Number) - 1.0;
  87. END;
  88.  
  89.  
  90.  
  91. { ----- Inverse cosine ----- }
  92. FUNCTION ArcCos (Number: Real): Real;
  93. BEGIN
  94.    IF (Number < -1.0) OR (Number > 1.0) THEN      { error }
  95.       ArcCos := 99999.0
  96.    ELSE
  97.       ArcCos := PI / 2.0 - ArcSin(Number);
  98. END;
  99.  
  100.  
  101.  
  102. { ----- Inverse hyperbolic cosine ----- }
  103. FUNCTION ArcCosH (Number: Real): Real;
  104. BEGIN
  105.    ArcCosH := Log(Number + SQRT(SQR(Number) - 1.0));
  106. END;
  107.  
  108.  
  109.  
  110. { ----- Inverse sine ----- }
  111. FUNCTION ArcSin (Number: Real): Real;
  112. VAR
  113.    Negate: Boolean;
  114.    tmp: Real;
  115. BEGIN
  116.    IF Number < 0.0 THEN BEGIN
  117.       Number := -Number;
  118.       Negate := TRUE;
  119.    END
  120.    ELSE
  121.       Negate := FALSE;
  122.    IF Number > 1.0 THEN BEGIN
  123.       tmp := 99999.0;
  124.       Negate := FALSE;
  125.    END
  126.    ELSE BEGIN
  127.       tmp := SQRT(1.0 - SQR(Number));
  128.       IF Number > 0.7 THEN
  129.          tmp := PI / 2.0 - ArcTan(tmp / Number)
  130.       ELSE
  131.          tmp := ArcTan(Number / tmp);
  132.    END;
  133.    IF Negate THEN
  134.       ArcSin := -tmp
  135.    ELSE
  136.       ArcSin := tmp;
  137. END;
  138.  
  139.  
  140.  
  141. { ----- Inverse hyperbolic sine ----- }
  142. FUNCTION ArcSinH (Number: Real): Real;
  143. BEGIN
  144.    ArcSinH := Log(Number + SQRT(SQR(Number) + 1.0));
  145. END;
  146.  
  147.  
  148.  
  149. { ----- Inverse hyperbolic tangent ----- }
  150. FUNCTION ArcTanH (Number: Real): Real;
  151. BEGIN
  152.    ArcTanH := Log((1.0 + Number) / (1.0 - Number)) / 2.0;
  153. END;
  154.  
  155.  
  156.  
  157. { ----- Convert degrees to radians ----- }
  158. FUNCTION Deg2Rad (Number: Real): Real;
  159. BEGIN
  160.    Deg2Rad := Number * PI / 180.0;
  161. END;
  162.  
  163.  
  164.  
  165. { ----- e (base of the natural logarithms) ----- }
  166. FUNCTION e: Real;
  167. BEGIN
  168.    e := 2.7182818284590452353602874713526624977572470936999595749669676;
  169. END;
  170.  
  171.  
  172.  
  173. { ----- Hyperbolic cosine ----- }
  174. FUNCTION CosH (Number: Real): Real;
  175. BEGIN
  176.    IF Number < 0.0 THEN
  177.       Number := - Number;
  178.    IF Number > 21.0 THEN
  179.       CosH := Exp(Number) / 2.0
  180.    ELSE
  181.       CosH := (Exp(Number) + Exp(-Number)) / 2.0;
  182. END;
  183.  
  184.  
  185.  
  186. { ----- Cotangent ----- }
  187. FUNCTION Cot (Number: Real): Real;
  188. BEGIN
  189.    Cot := 1.0 / Tan(Number);
  190. END;
  191.  
  192.  
  193.  
  194. { ----- Cosecant ----- }
  195. FUNCTION Csc (Number: Real): Real;
  196. BEGIN
  197.    Csc := 1.0 / Sin(Number);
  198. END;
  199.  
  200.  
  201.  
  202. { ----- Error Function ----- }
  203. FUNCTION Erf (Number: Real): Real;
  204. VAR
  205.    J, N: Integer;
  206.    S: Real;
  207. BEGIN
  208.    N := Trunc(14.0 * Number + 3.0);
  209.    S := 1.0 / (2.0 * N - 1.0);
  210.    FOR J := N - 1 DOWNTO 1 DO
  211.       S := 1.0 / (2.0 * J - 1.0) - SQR(Number) / J * S;
  212.    Erf := Number / 0.8862269254527581 * S;
  213. END;
  214.  
  215.  
  216.  
  217. { ----- Factorial ----- }
  218. FUNCTION Fact (Number: Integer): Real;
  219. VAR
  220.    Result: Real;
  221.    tmp: Integer;
  222. BEGIN
  223.    Result := 1.0;
  224.    FOR tmp := 2 TO Number DO
  225.       Result := Result * tmp;
  226.    Fact := Result;
  227. END;
  228.  
  229.  
  230.  
  231. { ----- Logarithm (base 10) ----- }
  232. FUNCTION Log (Number: Real): Real;
  233. BEGIN
  234.    Log := Ln(Number) / Ln(10.0);
  235. END;
  236.  
  237.  
  238.  
  239. { ----- Convert radians to degrees ----- }
  240. FUNCTION Rad2Deg (Number: Real): Real;
  241. BEGIN
  242.    Rad2Deg := Number * 180.0 / PI;
  243. END;
  244.  
  245.  
  246.  
  247. { ----- Raise a number to a power (a feature oddly lacking in Pascal). }
  248. FUNCTION Raise (Number: Real; Power: Integer): Real;
  249. VAR
  250.    tmp: Integer;
  251.    Result: Real;
  252. BEGIN
  253.    Result := 1.0;
  254.    FOR tmp := 1 TO Power DO
  255.       Result := Result * Number;
  256.    Raise := Result;
  257. END;     { Raise }
  258.  
  259.  
  260.  
  261. { ----- Secant ----- }
  262. FUNCTION Sec (Number: Real): Real;
  263. BEGIN
  264.    Sec := 1.0 / Cos(Number);
  265. END;
  266.  
  267.  
  268.  
  269. { ----- Hyperbolic sine ----- }
  270. FUNCTION SinH (Number: Real): Real;
  271. VAR
  272.    Negate: Boolean;
  273.    p0, p1, p2, p3, q0, q1, q2, tmp, tmp1, tmp2, tmpsq: Real;
  274. BEGIN
  275.    p0 := -630767.3640497716991184787251;
  276.    p1 := -89912.72022039509355398013511;
  277.    p2 := -2894.211355989563807284660366;
  278.    p3 := -26.30563213397497062819489;
  279.    q0 := -630767.3640497716991212077277;
  280.    q1 := 15215.17378790019070696485176;
  281.    q2 := -173.678953558233699533450911;
  282.    IF Number < 0.0 THEN BEGIN
  283.       Number := -Number;
  284.       Negate := TRUE;
  285.    END
  286.    ELSE
  287.       Negate := FALSE;
  288.    IF Number > 21.0 THEN
  289.       tmp := Exp(Number) / 2.0
  290.    ELSE IF Number > 0.5 THEN
  291.       tmp := (Exp(Number) - Exp(-Number)) / 2.0
  292.    ELSE BEGIN
  293.       tmpsq := SQR(Number);
  294.       tmp1 := (((tmpsq * p3 + p2) * tmpsq + p1) * tmpsq + p0) * Number;
  295.       tmp2 := ((tmpsq + q2) * tmpsq + q1) * tmpsq + q0;
  296.       tmp := tmp1 / tmp2;
  297.    END;
  298.    IF Negate THEN
  299.       SinH := -tmp
  300.    ELSE
  301.       SinH := tmp;
  302. END;
  303.  
  304.  
  305.  
  306. { ----- Tangent ----- }
  307. FUNCTION Tan (Number: Real): Real;
  308. BEGIN
  309.    Tan := Sin(Number) / Cos(Number);
  310. END;
  311.  
  312.  
  313.  
  314. { ----- Hyperbolic tangent ----- }
  315. FUNCTION TanH (Number: Real): Real;
  316. VAR
  317.    Negate: Boolean;
  318.    tmp: Real;
  319. BEGIN
  320.    IF Number < 0.0 THEN BEGIN
  321.       Number := -Number;
  322.       Negate := TRUE;
  323.    END
  324.    ELSE
  325.       Negate := FALSE;
  326.    IF Number > 21.0 THEN     { error }
  327.       TanH := 99999
  328.    ELSE BEGIN
  329.       tmp := SinH(Number) / CosH(Number);
  330.       IF Negate THEN
  331.          TanH := -tmp
  332.       ELSE
  333.          TanH := tmp;
  334.    END;
  335. END;
  336.  
  337.  
  338.  
  339. { =========================================================================== }
  340.  
  341.  
  342.  
  343. { ----- This is the main evaluation routine ----- }
  344. PROCEDURE Evaluate (Expr: String; VAR Result: Real; VAR ErrCode: Integer);
  345. VAR
  346.    tmp: Integer;
  347. BEGIN
  348.    WHILE (Pos(' ', Expr) > 0) DO
  349.       Delete(Expr, Pos(' ', Expr), 1);
  350.    WHILE (Pos('**', Expr) > 0) DO BEGIN
  351.       tmp := Pos('**', Expr);
  352.       Delete(Expr, tmp, 1);
  353.       Expr[tmp] := '^';
  354.    END;
  355.    IF Length(Expr) > 0 THEN
  356.       IF ParensOk(Expr) THEN BEGIN
  357.          FOR tmp := 1 TO Length(Expr) DO
  358.             Expr[tmp] := Upcase(Expr[tmp]);
  359.          ErrCode := 0;
  360.          FixPrecedence(Expr);
  361.          Result := Eval(Expr, ErrCode);
  362.       END
  363.       ELSE
  364.          ErrCode := 4
  365.    ELSE
  366.       ErrCode := 8;
  367. END;     { Evaluate }
  368.  
  369.  
  370.  
  371. { ----- This adds parentheses to force evaluation by normal algebraic
  372.         precedence (negation, exponentiation, multiplication and division,
  373.         addition and subtraction) }
  374. PROCEDURE AddParen (VAR Expr: String; Posn, WhichWay: Integer);
  375. VAR
  376.    Done: Boolean;
  377.    ch: Char;
  378.    Depth: Integer;
  379. BEGIN
  380.    Done := FALSE;
  381.    IF WhichWay < 0 THEN BEGIN
  382.       REPEAT
  383.          Dec(Posn);
  384.          IF Posn < 1 THEN BEGIN
  385.             Expr := '(' + Expr;
  386.             Done := TRUE;
  387.          END
  388.          ELSE BEGIN
  389.             ch := Expr[Posn];
  390.             IF Pos(ch, '^*/+-') > 0 THEN BEGIN
  391.                Insert('(', Expr, Posn + 1);
  392.                Done := TRUE;
  393.             END
  394.             ELSE IF ch = ')' THEN BEGIN
  395.                Depth := 1;
  396.                REPEAT
  397.                   Dec(Posn);
  398.                   IF Posn > 0 THEN BEGIN
  399.                      ch := Expr[Posn];
  400.                      IF ch = '(' THEN
  401.                         Dec(Depth)
  402.                      ELSE IF ch = ')' THEN
  403.                         Inc(Depth);
  404.                   END
  405.                   ELSE
  406.                      Depth := 0;
  407.                UNTIL Depth = 0;
  408.                IF Posn < 1 THEN
  409.                   Posn := 1;
  410.                Insert('(', Expr, Posn + 1);
  411.                Done := TRUE;
  412.             END;
  413.          END;
  414.       UNTIL Done;
  415.    END
  416.    ELSE
  417.       REPEAT
  418.          Inc(Posn);
  419.          IF Posn > Length(Expr) THEN BEGIN
  420.             Expr := Expr + ')';
  421.             Done := TRUE;
  422.          END
  423.          ELSE BEGIN
  424.             ch := Expr[Posn];
  425.             IF Pos(ch, '^*/+-') > 0 THEN BEGIN
  426.                Insert(')', Expr, Posn);
  427.                Done := TRUE;
  428.             END
  429.             ELSE IF ch = '(' THEN BEGIN
  430.                Depth := 1;
  431.                REPEAT
  432.                   Inc(Posn);
  433.                   IF Posn <= Length(Expr) THEN BEGIN
  434.                      ch := Expr[Posn];
  435.                      IF ch = ')' THEN
  436.                         Dec(Depth)
  437.                      ELSE IF ch = '(' THEN
  438.                         Inc(Depth);
  439.                   END
  440.                   ELSE
  441.                      Depth := 0;
  442.                UNTIL Depth = 0;
  443.                IF Posn > Length(Expr) THEN
  444.                   Posn := Length(Expr);
  445.                Insert(')', Expr, Posn);
  446.                Done := TRUE;
  447.             END;
  448.          END;
  449.       UNTIL Done;
  450. END;    { AddParen }
  451.  
  452.  
  453.  
  454. { ----- This recursive function is the heart of the expression evaluator. }
  455. FUNCTION Eval (VAR Expr: String; VAR ErrCode: Integer): Real;
  456. VAR
  457.    LVal, tmp: Real;
  458. BEGIN
  459.    LVal := Factor(Expr, ErrCode);
  460.    IF ErrCode = 0 THEN
  461.       CASE Expr[1] OF
  462.          '+': BEGIN
  463.                  Delete(Expr, 1, 1);
  464.                  LVal := LVal + Eval(Expr, ErrCode);
  465.               END;
  466.          '-': BEGIN
  467.                  Delete(Expr, 1, 1);
  468.                  LVal := LVal - Eval(Expr, ErrCode);
  469.               END;
  470.          '*': BEGIN
  471.                  Delete(Expr, 1, 1);
  472.                  LVal := LVal * Eval(Expr, ErrCode);
  473.               END;
  474.          '/': BEGIN
  475.                  Delete(Expr, 1, 1);
  476.                  tmp := Eval(Expr, ErrCode);
  477.                  IF ErrCode = 0 THEN
  478.                     IF tmp = 0.0 THEN
  479.                        ErrCode := 9
  480.                     ELSE
  481.                        LVal := LVal / tmp;
  482.               END;
  483.          '^': BEGIN
  484.                  Delete(Expr, 1, 1);
  485.                  LVal := Raise(LVal, Trunc(Eval(Expr, ErrCode)));
  486.               END;
  487.          ')': Delete(Expr, 1, 1);
  488.       END;     { CASE }
  489.    Eval := LVal;
  490. END;     { Eval }
  491.  
  492.  
  493.  
  494. { ----- A recursive evaluation helper, this function gets the leftmost term
  495.         that can be dealt with at this point in the evaluation. }
  496. FUNCTION Factor (VAR Expr: String; VAR ErrCode: Integer): Real;
  497. VAR
  498.    Negate: Boolean;
  499.    RVal: Real;
  500. BEGIN
  501.    RVal := 0.0;
  502.    IF Expr[1] = '-' THEN BEGIN
  503.       Negate := TRUE;
  504.       Delete(Expr, 1, 1);
  505.    END
  506.    ELSE
  507.       Negate := FALSE;
  508.    IF Expr[1] <> '(' THEN
  509.       RVal := Term(Expr, ErrCode)
  510.    ELSE BEGIN
  511.       Delete(Expr, 1, 1);
  512.       RVal := Eval(Expr, ErrCode);
  513.    END;
  514.    IF Negate THEN
  515.       Factor := -RVal
  516.    ELSE
  517.       Factor := RVal;
  518. END;     { Factor }
  519.  
  520.  
  521.  
  522. { ----- Since the evaluation function doesn't naturally evaluate expressions
  523.         using algebraic precedence, but does understand parentheses...
  524.         This routine adds parentheses to force the proper precedence. }
  525. PROCEDURE FixPrecedence (VAR Expr: String);
  526. VAR
  527.    Posn, tmp: Integer;
  528. BEGIN
  529.    Expr := '(' + Expr + ')';
  530.    Posn := 2;
  531.    REPEAT
  532.       IF Expr[Posn] = '-' THEN
  533.          IF NOT(Expr[Posn - 1] IN ['0'..'9','A'..'Z']) THEN BEGIN
  534.             AddParen(Expr, Posn, 1);
  535.             AddParen(Expr, Posn, -1);
  536.             Inc(Posn, 2);
  537.          END
  538.          ELSE
  539.             Inc(Posn)
  540.       ELSE
  541.          Inc(Posn);
  542.    UNTIL Posn > Length(Expr);
  543.    Posn := 1;
  544.    REPEAT
  545.       IF Expr[Posn] <> Locase(Expr[Posn]) THEN BEGIN
  546.          AddParen(Expr, Posn, 1);
  547.          AddParen(Expr, Posn, -1);
  548.          Inc(Posn, 2);
  549.       END
  550.       ELSE
  551.          Inc(Posn);
  552.    UNTIL Posn > Length(Expr);
  553.    Posn := 1;
  554.    REPEAT
  555.       IF Expr[Posn] = '^' THEN BEGIN
  556.          AddParen(Expr, Posn, 1);
  557.          AddParen(Expr, Posn, -1);
  558.          Inc(Posn, 2);
  559.       END
  560.       ELSE
  561.          Inc(Posn);
  562.    UNTIL Posn > Length(Expr);
  563.    Posn := 1;
  564.    REPEAT
  565.       IF Pos(Expr[Posn], '*/') > 0 THEN BEGIN
  566.          AddParen(Expr, Posn, 1);
  567.          AddParen(Expr, Posn, -1);
  568.          Inc(Posn, 2);
  569.       END
  570.       ELSE
  571.          Inc(Posn);
  572.    UNTIL Posn > Length(Expr);
  573.    Posn := 1;
  574.    REPEAT
  575.       IF Pos(Expr[Posn], '+-') > 0 THEN BEGIN
  576.          AddParen(Expr, Posn, 1);
  577.          AddParen(Expr, Posn, -1);
  578.          Inc(Posn, 2);
  579.       END
  580.       ELSE
  581.          Inc(Posn);
  582.    UNTIL Posn > Length(Expr);
  583.    Delete(Expr, 1, 1);
  584.    Delete(Expr, Length(Expr), 1);
  585. END;     { FixPrecedence }
  586.  
  587.  
  588.  
  589. { ----- Determine whether a character may be construed as being numeric. }
  590. FUNCTION IsDigit (Expr: String): Boolean;
  591. BEGIN
  592.    IF Length(Expr) > 0 THEN
  593.       IsDigit := (Pos(Expr[1], '0123456789.') > 0)
  594.    ELSE
  595.       IsDigit := FALSE;
  596. END;     { IsDigit }
  597.  
  598.  
  599.  
  600. { ----- Convert a character to lowercase. }
  601. FUNCTION LoCase (ch: Char): Char;
  602. BEGIN
  603.    IF ch IN ['A'..'Z'] THEN
  604.       LoCase := CHR(ORD(ch) XOR 32)
  605.    ELSE
  606.       LoCase := ch
  607. END;     { LoCase }
  608.  
  609.  
  610.  
  611. { ----- Check to make sure parentheses are balanced. }
  612. FUNCTION ParensOk (Expr: String): Boolean;
  613. VAR
  614.    Parens, Posn: Integer;
  615. BEGIN
  616.    Parens := 0;
  617.    FOR Posn := 1 TO Length(Expr) DO
  618.       IF Expr[Posn] = '(' THEN
  619.          Inc(Parens)
  620.       ELSE IF Expr[Posn] = ')' THEN
  621.          Dec(Parens);
  622.    ParensOk := (Parens = 0);
  623. END;     { ParensOk }
  624.  
  625.  
  626.  
  627. { ----- This grabs a number from the expression. }
  628. FUNCTION Term (VAR Expr: String; VAR ErrCode: Integer): Real;
  629. VAR
  630.    junk: Integer;
  631.    RVal: Real;
  632.    ch: char;
  633.    tmp: String;
  634. BEGIN
  635.    RVal := 0.0;
  636.    ch := Upcase(Expr[1]);
  637.    IF ch <> Locase(ch) THEN BEGIN
  638.       tmp := '';
  639.       REPEAT
  640.          tmp := tmp + ch;
  641.          Delete(Expr, 1, 1);
  642.          ch := Upcase(Expr[1]);
  643.       UNTIL (ch = Locase(ch)) OR (Length(Expr) = 0);
  644.       IF tmp = 'ABS' THEN
  645.          IF ch = '(' THEN BEGIN
  646.             Delete(Expr, 1, 1);
  647.             RVal := ABS(Eval(Expr, ErrCode))
  648.          END
  649.          ELSE
  650.             ErrCode := 1
  651.       ELSE IF tmp = 'ACOS' THEN
  652.          IF ch = '(' THEN BEGIN
  653.             Delete(Expr, 1, 1);
  654.             RVal := ArcCos(Eval(Expr, ErrCode))
  655.          END
  656.          ELSE
  657.             ErrCode := 1
  658.       ELSE IF tmp = 'ASIN' THEN
  659.          IF ch = '(' THEN BEGIN
  660.             Delete(Expr, 1, 1);
  661.             RVal := ArcSin(Eval(Expr, ErrCode))
  662.          END
  663.          ELSE
  664.             ErrCode := 1
  665.       ELSE IF tmp = 'ATAN' THEN
  666.          IF ch = '(' THEN BEGIN
  667.             Delete(Expr, 1, 1);
  668.             RVal := ArcTan(Eval(Expr, ErrCode))
  669.          END
  670.          ELSE
  671.             ErrCode := 1
  672.       ELSE IF tmp = 'COS' THEN
  673.          IF ch = '(' THEN BEGIN
  674.             Delete(Expr, 1, 1);
  675.             RVal := COS(Eval(Expr, ErrCode))
  676.          END
  677.          ELSE
  678.             ErrCode := 1
  679.       ELSE IF tmp = 'FRAC' THEN
  680.          IF ch = '(' THEN BEGIN
  681.             Delete(Expr, 1, 1);
  682.             RVal := Eval(Expr, ErrCode);
  683.             RVal := RVal - INT(RVal);
  684.          END
  685.          ELSE
  686.             ErrCode := 1
  687.       ELSE IF tmp = 'INT' THEN
  688.          IF ch = '(' THEN BEGIN
  689.             Delete(Expr, 1, 1);
  690.             RVal := INT(Eval(Expr, ErrCode))
  691.          END
  692.          ELSE
  693.             ErrCode := 1
  694.       ELSE IF tmp = 'LOG' THEN
  695.          IF ch = '(' THEN BEGIN
  696.             Delete(Expr, 1, 1);
  697.             RVal := LOG(Eval(Expr, ErrCode))
  698.          END
  699.          ELSE
  700.             ErrCode := 1
  701.       ELSE IF tmp = 'PI' THEN
  702.          RVal := 3.141593
  703.       ELSE IF tmp = 'SIN' THEN
  704.          IF ch = '(' THEN BEGIN
  705.             Delete(Expr, 1, 1);
  706.             RVal := SIN(Eval(Expr, ErrCode))
  707.          END
  708.          ELSE
  709.             ErrCode := 1
  710.       ELSE IF tmp = 'SQRT' THEN
  711.          IF ch = '(' THEN BEGIN
  712.             Delete(Expr, 1, 1);
  713.             RVal := SQRT(Eval(Expr, ErrCode))
  714.          END
  715.          ELSE
  716.             ErrCode := 1
  717.       ELSE IF tmp = 'TAN' THEN
  718.          IF ch = '(' THEN BEGIN
  719.             Delete(Expr, 1, 1);
  720.             RVal := TAN(Eval(Expr, ErrCode))
  721.          END
  722.          ELSE
  723.             ErrCode := 1
  724.       ELSE
  725.          ErrCode := 3
  726.    END
  727.    ELSE IF IsDigit(Expr) THEN BEGIN
  728.       tmp := '';
  729.       WHILE IsDigit(Expr) DO BEGIN
  730.          tmp := tmp + Expr[1];
  731.          Delete(Expr, 1, 1);
  732.       END;
  733.       Val(tmp, RVal, junk);
  734.    END
  735.    ELSE
  736.       ErrCode := 2;
  737.    Term := RVal;
  738. END;     { Term }
  739.  
  740.  
  741.  
  742. END.     { ExtMath UNIT }
  743.