home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / 1991 / 02 / tricks / arithmos.pas next >
Encoding:
Pascal/Delphi Source File  |  1990-11-07  |  13.7 KB  |  506 lines

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