home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / extra18 / toolbox / arithmos.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1992-01-21  |  13.7 KB  |  524 lines

  1. (*-------------------------------------------------- *)
  2. (*                 ARITHMOS.PAS                      *)
  3. (*        Arithmetik-Unit für Turbo Pascal ab 5.5    *)
  4. (*   (c) 1990, 1992 Dirk Hillbrecht & DMV-Verlag     *)
  5. (* ------------------------------------------------- *)
  6. {$A+,B-,D-,E-,F-,I-,N-,O-,R-,V-}
  7.  
  8. UNIT Arithmos;
  9.  
  10. INTERFACE
  11.  
  12. CONST
  13.   Ln10 = 2.3025850930;           { Ln 10              }
  14.   Ln2  = 0.6931471856;           { Ln 2               }
  15.   e    = 2.718281829;            { Eulersche Zahl     }
  16.   pi   = 3.141592654;            { die KreiskonsTante }
  17.  
  18.   { wichtige physikalische Konstanten,
  19.                       jeweils in normierten Einheiten }
  20.  
  21.   phy_epsilon0 =  8.854219e-12;
  22.                            { elektrische Feldkonstante}
  23.   phy_my0      = 12.56637061e-7;
  24.                            { magnetische Feldkonstante}
  25.   phy_na       =  6.023e23;    { Avogadro-Konstante   }
  26.   phy_c        =  2.997935e8;  { Lichtgeschwindigkeit }
  27.   phy_g        =  9.80665;     { Fallbeschleunigung   }
  28.   phy_k        =  1.3804e-23;  { Boltzmann-Konstante  }
  29.  
  30.   { alLgemeines Funktionsergebnis im Fehlerfall }
  31.   MaxReal = 1e+38;
  32.  
  33.   { Schalter für die Winkelfunktionsdarstellung }
  34.   rad = 0;
  35.   deg = 1;
  36.   gra = 2;
  37.  
  38.  
  39.   FUNCTION ArithResult(x : REAL) : SHORTINT;
  40.     { wenn |x| ≥ MaxReal,
  41.       dann Fehlermeldung zurückgeben }
  42.  
  43.   FUNCTION ArithErrMsg(ErrNummer  : SHORTINT) : STRING;
  44.     { Klartextfehlermeldung aus <ArithResult> erzeugen}
  45.  
  46.   PROCEDURE Trigonomodus(modus : WORD);
  47.     { einstellen der Einheit des Winkelmaßes }
  48.  
  49.   FUNCTION Sqr(x : REAL) : REAL;
  50.     { berechnet x² mit Test auf Bereichsüberschreitung}
  51.  
  52.   FUNCTION Sqrt(x : REAL) : REAL;
  53.     { berechnet √x mit Plausibilitätstest }
  54.  
  55.   FUNCTION Faku(x : REAL) : REAL;
  56.     { berechnet x!, wenn x ε N und 0 ≤ x ≤ 36 gilt }
  57.  
  58.   FUNCTION Power(x, y : REAL) : REAL;
  59.     { x^y, auch gebrochene und negative Zahlen erlaubt}
  60.  
  61.   FUNCTION PwrOfTen(epn : REAL) : REAL;
  62.     { 10^epn }
  63.  
  64.   FUNCTION Exp(x : REAL) : REAL;
  65.     { berechnet e^x mit Plausibilitätsprüfung }
  66.  
  67.   FUNCTION Log(b, z : REAL) : REAL;
  68.     { berechnet den Logarithmus von z zur Basis b }
  69.  
  70.   FUNCTION Lg(x : REAL) : REAL;
  71.     { Logarithmus zur Basis 10 }
  72.  
  73.   FUNCTION Lb(x : REAL) : REAL;
  74.     { Logarithmus zur Basis 2 }
  75.  
  76.   FUNCTION Ln(x : REAL) : REAL;
  77.     { berechnet den Logarithmus zur Basis e mit Test }
  78.     { auf Gültigkeit }
  79.  
  80.   { ---  Trigonometrie  ----------------------------- }
  81.   { alle trigonometrischen Funktionen, die einen      }
  82.   { Winkel erwarten, interpretieren diesen Winkel in  }
  83.   { der eingestellten Einheit (rad/deg/gra); umgekehrt}
  84.   { geben die Umkehrfunktionen ihren Winkel in dieser }
  85.   { Einheit zurück                                    }
  86.  
  87.   FUNCTION Sin(x : REAL) : REAL;
  88.  
  89.   FUNCTION Cos(x : REAL) : REAL;
  90.  
  91.   FUNCTION Tan(x : REAL) : REAL;
  92.  
  93.   FUNCTION Cot(x : REAL) : REAL;
  94.  
  95.   FUNCTION ArcSin(x : REAL) : REAL;
  96.  
  97.   FUNCTION ArcCos(x : REAL) : REAL;
  98.  
  99.   FUNCTION ArcTan(x : REAL) : REAL;
  100.  
  101.   FUNCTION ArcCot(x : REAL) : REAL;
  102.  
  103.   FUNCTION Sinh(x : REAL) : REAL;
  104.  
  105.   FUNCTION Cosh(x : REAL) : REAL;
  106.  
  107.   FUNCTION Tanh(x : REAL) : REAL;
  108.  
  109.   FUNCTION Coth(x : REAL) : REAL;
  110.  
  111.   FUNCTION ArSinh(x : REAL) : REAL;
  112.  
  113.   FUNCTION ArCosh(x : REAL) : REAL;
  114.  
  115.   FUNCTION ArTanh(x : REAL) : REAL;
  116.  
  117.   FUNCTION ArCoth(x : REAL) : REAL;
  118.  
  119.   (*  --- Zusatzroutinen --------------------------- *)
  120.  
  121.   FUNCTION RtoStr(zahl : REAL) : STRING;
  122.     { formt eine REAL-Zahl in einen STRING um, kleine }
  123.     { Zahlen werden normal, große in wissen-          }
  124.     { schaftlicher Exponentialschreibweise darge-     }
  125.     { stellt, Rechenfehler werden in gewissen Grenzen }
  126.     { gerundet.                                       }
  127.  
  128. IMPLEMENTATION
  129.  
  130. CONST
  131.   durchpi180         = 1.745329252e-2;   { π / 180 }
  132.   durch180pi         = 5.729577951e1;    { 180 / π }
  133.   durchpi200         = 1.570796327e-2;   { π / 200 }
  134.   durch200pi         = 6.366197724e1;    { 200 / π }
  135.  
  136.   pi_haLbe           = 1.570796327;      { π / 2   }
  137.   minExp             = -88;
  138.   maxExp             = 88;
  139.  
  140.   isNotRad : BOOLEAN = TRUE;
  141.                  { TRUE : RAD / FALSE : umzurechnen }
  142.  
  143. VAR
  144.   toRad, fromRad, hilf : REAL;
  145.   InternError          : SHORTINT;
  146.  
  147.  
  148.   PROCEDURE RadWinkel(VAR Argument : REAL);
  149.   { Winkel in beliebiger Einheit nach RAD konvertieren}
  150.   BEGIN
  151.     IF isNotRad THEN Argument := Argument * toRad;
  152.   END;
  153.  
  154.   FUNCTION NormWinkel(a : REAL) : REAL;
  155.   { RAD-Winkel in offizielle Einheit
  156.     zurückkonvertieren }
  157.   BEGIN
  158.     IF isNotRad THEN NormWinkel := a * fromRad
  159.                 ELSE NormWinkel := a;
  160.   END;
  161.  
  162.   FUNCTION ArithResult(x : REAL) : SHORTINT;
  163.   BEGIN
  164.     IF (Abs(x) >= MaxReal) THEN
  165.       ArithResult := InternError
  166.     ELSE
  167.       ArithResult := 0;
  168.     InternError := -127;
  169.   END;
  170.  
  171.   PROCEDURE Trigonomodus(modus : WORD);
  172.   BEGIN
  173.     CASE modus OF
  174.       rad : isNotRad := FALSE;
  175.       deg : BEGIN
  176.               toRad    := durchpi180;
  177.               fromRad  := durch180pi;
  178.               isNotRad := TRUE;
  179.             END;
  180.       gra : BEGIN
  181.               toRad    := durchpi200;
  182.               fromRad  := durch200pi;
  183.               isNotRad := TRUE;
  184.             END;
  185.     END;
  186.   END;
  187.  
  188.   FUNCTION Faku(x : REAL) : REAL;
  189.   VAR
  190.     i       : WORD;
  191.     Zaehler : REAL;
  192.   BEGIN
  193.     InternError := -1;
  194.     IF (Abs(x-Round(x)) > 1e-6) OR (x < 0) OR
  195.                                    (x > 36) THEN
  196.       Zaehler := MaxReal
  197.     ELSE BEGIN
  198.       Zaehler := 1;
  199.       i := Round(x);
  200.       WHILE i > 1 DO BEGIN
  201.         Zaehler := Zaehler * i;
  202.         Dec(i);
  203.       END;
  204.     END;
  205.     Faku := Zaehler;
  206.   END;
  207.  
  208.   FUNCTION Sqr(x : REAL) : REAL;
  209.   BEGIN
  210.     InternError := -2;
  211.     IF Abs(x) < 1e19 THEN Sqr := System.Sqr(x)
  212.                      ELSE Sqr := MaxReal;
  213.   END;
  214.  
  215.   FUNCTION Sqrt(x : REAL) : REAL;
  216.   BEGIN
  217.     InternError := -3;
  218.     IF x < 0.0 THEN Sqrt := MaxReal
  219.                ELSE Sqrt := System.Sqrt(x);
  220.   END;
  221.  
  222.   FUNCTION Power(x, y : REAL) : REAL;
  223.   BEGIN
  224.     InternError := -4;
  225.     IF (x <> 0.0) OR (y <> 0.0) THEN BEGIN
  226.       IF x > 0.0 THEN
  227.         Power := Exp(y*Ln(x))
  228.       ELSE IF x = 0.0 THEN
  229.         Power := 0.0
  230.       ELSE IF Frac(y) = 0 THEN
  231.         IF Odd(Round(y)) THEN
  232.           Power := -Exp(y*Ln(Abs(x)))
  233.         ELSE
  234.           Power := Exp(y*Ln(Abs(x)))
  235.       ELSE BEGIN
  236.         Power := MaxReal;
  237.         InternError := -5;
  238.       END;
  239.     END ELSE Power := MaxReal;
  240.   END;
  241.  
  242.   FUNCTION PwrOfTen(epn : REAL) : REAL;
  243.   BEGIN
  244.     PwrOfTen := Exp(epn*Ln10);
  245.   END;
  246.  
  247.   FUNCTION Exp(x : REAL) : REAL;
  248.   BEGIN
  249.     Exp := MaxReal;
  250.     IF x > minExp THEN
  251.       IF x < maxExp THEN
  252.         Exp := System.Exp(x)
  253.       ELSE
  254.         InternError := -6
  255.     ELSE
  256.       InternError := -7;
  257.   END;
  258.  
  259.   FUNCTION Log(b, z : REAL) : REAL;
  260.   BEGIN
  261.     Log := MaxReal;
  262.     IF b > 0.0 THEN
  263.       IF z > 0.0 THEN BEGIN
  264.         hilf := System.Ln(b);
  265.         IF Abs(hilf) > 1e-7 THEN
  266.           Log := System.Ln(z)/hilf
  267.         ELSE
  268.           InternError := -8
  269.         END
  270.         ELSE InternError := -9
  271.       ELSE InternError := -10;
  272.   END;
  273.  
  274.   FUNCTION Lg(x : REAL) : REAL;
  275.   BEGIN
  276.     InternError := -9;
  277.     IF x > 0.0 THEN Lg := System.Ln(x)/Ln10
  278.                ELSE Lg := MaxReal;
  279.   END;
  280.  
  281.   FUNCTION Lb(x : REAL) : REAL;
  282.   BEGIN
  283.     InternError := -9;
  284.     IF x > 0.0 THEN Lb := System.Ln(x)/Ln2
  285.                ELSE Lb := MaxReal;
  286.   END;
  287.  
  288.   FUNCTION Ln(x : REAL) : REAL;
  289.   BEGIN
  290.     InternError := -9;
  291.     IF x > 0.0 THEN Ln := System.Ln(x)
  292.                ELSE Ln := MaxReal;
  293.   END;
  294.  
  295.   FUNCTION Sin(x : REAL) : REAL;
  296.   BEGIN
  297.     RadWinkel(x);
  298.     Sin := System.Sin(x);
  299.   END;
  300.  
  301.   FUNCTION Cos(x : REAL) : REAL;
  302.   BEGIN
  303.     RadWinkel(x);
  304.     Cos := System.Cos(x);
  305.   END;
  306.  
  307.   FUNCTION Tan(x : REAL) : REAL;
  308.   BEGIN
  309.     InternError := -11;
  310.     RadWinkel(x);
  311.     hilf := System.Cos(x);
  312.     IF hilf <> 0.0 THEN Tan := System.Sin(x)/hilf
  313.                    ELSE Tan := MaxReal;
  314.   END;
  315.  
  316.   FUNCTION Cot(x : REAL) : REAL;
  317.   BEGIN
  318.     InternError := -11;
  319.     RadWinkel(x);
  320.     hilf := System.Sin(x);
  321.     IF hilf <> 0.0 THEN Cot := System.Cos(x)/hilf
  322.                    ELSE Cot := MaxReal;
  323.   END;
  324.  
  325.   FUNCTION ArcSin(x : REAL) : REAL;
  326.   BEGIN
  327.     InternError := -12;
  328.     hilf := Abs(x);
  329.     IF hilf > 1.0 THEN
  330.       ArcSin := MaxReal
  331.     ELSE IF hilf = 1.0 THEN
  332.       ArcSin := NormWinkel(x * pi_halbe)
  333.     ELSE
  334.       ArcSin :=
  335.       NormWinkel(System.ArcTan(x/Sqrt(1-Sqr(x))));
  336.   END;
  337.  
  338.   FUNCTION ArcCos(x : REAL) : REAL;
  339.   BEGIN
  340.     InternError := -12;
  341.     ArcCos := NormWinkel(pi_haLbe) - ArcSin(x);
  342.   END;
  343.  
  344.   FUNCTION ArcTan(x : REAL) : REAL;
  345.   BEGIN
  346.     ArcTan := Normwinkel(System.ArcTan(x));
  347.   END;
  348.  
  349.   FUNCTION ArcCot(x : REAL) : REAL;
  350.   BEGIN
  351.     ArcCot := NormWinkel(pi_halbe) - ArcTan(x);
  352.   END;
  353.  
  354.   FUNCTION Sinh(x : REAL) : REAL;
  355.   BEGIN
  356.     x := Exp(x);
  357.     Sinh := 0.5 * (x - 1/x);
  358.   END;
  359.  
  360.   FUNCTION Cosh(x : REAL) : REAL;
  361.   BEGIN
  362.     x := Exp(x);
  363.     Cosh := 0.5 * (x + 1/x);
  364.   END;
  365.  
  366.   FUNCTION Tanh(x : REAL) : REAL;
  367.   BEGIN
  368.     Tanh := 1 - 2/(1 + Exp(2 * x));
  369.     InternError := -13;
  370.   END;
  371.  
  372.   FUNCTION Coth(x : REAL) : REAL;
  373.   BEGIN
  374.     InternError := -13;
  375.     hilf := Sinh(x);
  376.     IF hilf <> 0 THEN Coth := Cosh(x) / hilf
  377.                  ELSE Coth := MaxReal;
  378.   END;
  379.  
  380.   FUNCTION ArSinh(x : REAL) : REAL;
  381.   BEGIN
  382.     ArSinh := Ln(x + System.Sqrt(Sqr(x) + 1));
  383.     InternError := -14;
  384.   END;
  385.  
  386.   FUNCTION ArCosh(x : REAL) : REAL;
  387.   BEGIN
  388.     IF x < 1 THEN
  389.       ArCosh := MaxReal
  390.     ELSE
  391.       ArCosh := Ln(x + System.Sqrt(Sqr(x) - 1));
  392.     InternError := -14;
  393.   END;
  394.  
  395.   FUNCTION ArTanh(x : REAL) : REAL;
  396.   BEGIN
  397.     IF Abs(x) < 1.0 THEN
  398.       ArTanh := 0.5 * Ln((1+x) / (1-x))
  399.     ELSE
  400.       ArTanh := MaxReal;
  401.     InternError := -14;
  402.   END;
  403.  
  404.   FUNCTION ArCoth(x : REAL) : REAL;
  405.   BEGIN
  406.     IF Abs(x) > 1 THEN
  407.       ArCoth := 0.5 * Ln((x+1) / (x-1))
  408.     ELSE
  409.       ArCoth := MaxReal;
  410.     InternError := -14;
  411.   END;
  412.  
  413.   FUNCTION RtoStr(zahl : REAL) : STRING;
  414.   VAR
  415.     i                    : INTEGER;
  416.     negativ, eneg        : BOOLEAN;
  417.     rExponent            : REAL;
  418.     Exponent             : INTEGER;
  419.     hstr1, hstr2, ausstr : STRING [21];
  420.     tstzahl              : REAL;
  421.   BEGIN
  422.     IF zahl = 0.0 THEN BEGIN
  423.       RtoStr := '0';
  424.       Exit;
  425.     END;
  426.     negativ := (zahl < 0.0);
  427.       { Zahl muß wegen Logarithmen immer positiv sein,}
  428.       { negativ wird ggf. außerhalb gespeichert.      }
  429.     IF negativ THEN ausstr := '-'
  430.                ELSE ausstr := '';
  431.     zahl := Abs(zahl);
  432.     rExponent := Ln(zahl)/Ln10;
  433.       { Exponent für spätere Normalisierung
  434.         herausfiltern  }
  435.     eneg := (rExponent < 0);
  436.     IF eneg THEN Exponent := Trunc(rExponent-1)
  437.             ELSE Exponent := Trunc(rExponent);
  438.     zahl := zahl / (Exp(Exponent * Ln10));
  439.     zahl := Int(zahl * 10e6) / 10e6;
  440.     tstzahl := Frac(zahl) * 1e7;
  441.     IF (Frac(tstzahl / 10) * 10) = 1 THEN
  442.       zahl := zahl -1e-7
  443.     ELSE BEGIN
  444.       tstzahl := tstzahl / 10;
  445.       tstzahl := Frac(tstzahl);
  446.       tstzahl := Round(tstzahl * 10);
  447.       IF tstzahl = 9 THEN zahl := zahl + 1e-7;
  448.     END;
  449.     WHILE zahl > 9.999999 DO BEGIN
  450.          { Sonderfall 1*10^nn auch noch normalisieren }
  451.          { (geschieht oben nicht korrekt)             }
  452.       zahl := zahl / 10;
  453.       Inc(Exponent)
  454.     END;
  455.     IF (Exponent < -3) OR (Exponent > 6) THEN BEGIN
  456.             { Unterscheidung zw. Darstellungen }
  457.             {      1.) Exponentialschreibweise }
  458.       Str(zahl:9:7, hstr1);
  459.                            { Zahl in STRING umwandeln }
  460.       i := Length(hstr1);
  461.       WHILE (hstr1[i] = '0') AND
  462.             (hstr1[i-1] <> '.') DO BEGIN
  463.         Delete(hstr1, i, 1);
  464.         Dec(i);
  465.       END;
  466.       Exponent := Abs(Exponent);
  467.       Str(Exponent:2, hstr2);
  468.       IF hstr2[1] = ' ' THEN hstr2[1] := '0';
  469.       ausstr := ausstr + hstr1 + 'e';
  470.       IF eneg THEN ausstr := ausstr + '-';
  471.       ausstr := ausstr + hstr2;
  472.     END ELSE BEGIN
  473.             {      2.) natürliche Schreibweise }
  474.       zahl := zahl * (Exp(Exponent * Ln10));
  475.       Str(zahl:20:10, hstr1);
  476.       WHILE hstr1[1] = ' ' DO Delete(hstr1, 1, 1);
  477.       Delete(hstr1, 9, 255);
  478.       i := Length(hstr1);
  479.       WHILE hstr1[i] = '0' DO BEGIN
  480.         Delete(hstr1, i, 1);
  481.         Dec(i);
  482.       END;
  483.       IF hstr1[i] = '.' THEN Delete(hstr1, i, 1);
  484.       ausstr := ausstr + hstr1;
  485.     END;
  486.     RtoStr := ausstr;
  487.   END;
  488.  
  489.   FUNCTION ArithErrMsg(ErrNummer : SHORTINT) : STRING;
  490.   BEGIN
  491.     CASE ErrNummer Of
  492.     0 : ArithErrMsg := 'kein Fehler';
  493.    -1 : ArithErrMsg := 'Fakultät zu groß';
  494.    -2 : ArithErrMsg := 'Quadratfunktion zu groß';
  495.    -3 : ArithErrMsg := 'WurzelArgument negativ';
  496.    -4 : ArithErrMsg := 'Potenz : 0^0 nicht definiert';
  497.    -5 : ArithErrMsg := 'Potenz : -x^(z/n) nicht ' +
  498.                        'definiert';
  499.    -6 : ArithErrMsg := 'Exp : Argument zu groß';
  500.    -7 : ArithErrMsg := 'Exp : Argument zu klein';
  501.    -8 : ArithErrMsg := 'Log : Basis darf nicht 1 sein';
  502.    -9 : ArithErrMsg := 'LogArithmusArgument muß > 0 ' +
  503.                        'sein';
  504.   -10 : ArithErrMsg := 'Log : Basis muß > 0 sein';
  505.   -11 : ArithErrMsg := 'Winkelfunktion hier nicht ' +
  506.                        'definiert';
  507.   -12 : ArithErrMsg := 'Winkelumkehrfunktion hier ' +
  508.                        'nicht definiert';
  509.   -13 : ArithErrMsg := 'hyp-Funktion hier nicht ' +
  510.                        'definiert';
  511.   -14 : ArithErrMsg := 'Area-Funktion hier nicht ' +
  512.                        'definiert';
  513.  -127 : ArithErrMsg := 'undifferenzierter ' +
  514.                        'Gleitkommafehler';
  515.     END;
  516.   END;
  517.  
  518. BEGIN
  519.   Trigonomodus(rad);
  520.   InternError := -127;
  521. END.
  522. (* ------------------------------------------------- *)
  523. (*               Ende von ARITHMOS.PAS               *)
  524.