| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449 |
- (*
- BSD 2-Clause License
- Copyright (c) 2013-2014, 2018-2022 Anton Krotov
- All rights reserved.
- *)
- MODULE Math;
- IMPORT SYSTEM;
- CONST
- pi* = 3.141592653589793;
- e* = 2.718281828459045;
- PROCEDURE IsNan* (x: REAL): BOOLEAN;
- VAR
- h, l: SET;
- BEGIN
- SYSTEM.GET(SYSTEM.ADR(x), l);
- SYSTEM.GET(SYSTEM.ADR(x) + 4, h)
- RETURN (h * {20..30} = {20..30}) & ((h * {0..19} # {}) OR (l * {0..31} # {}))
- END IsNan;
- PROCEDURE IsInf* (x: REAL): BOOLEAN;
- RETURN ABS(x) = SYSTEM.INF()
- END IsInf;
- PROCEDURE Max (a, b: REAL): REAL;
- VAR
- res: REAL;
- BEGIN
- IF a > b THEN
- res := a
- ELSE
- res := b
- END
- RETURN res
- END Max;
- PROCEDURE Min (a, b: REAL): REAL;
- VAR
- res: REAL;
- BEGIN
- IF a < b THEN
- res := a
- ELSE
- res := b
- END
- RETURN res
- END Min;
- PROCEDURE SameValue (a, b: REAL): BOOLEAN;
- VAR
- eps: REAL;
- res: BOOLEAN;
- BEGIN
- eps := Max(Min(ABS(a), ABS(b)) * 1.0E-12, 1.0E-12);
- IF a > b THEN
- res := (a - b) <= eps
- ELSE
- res := (b - a) <= eps
- END
- RETURN res
- END SameValue;
- PROCEDURE IsZero (x: REAL): BOOLEAN;
- RETURN ABS(x) <= 1.0E-12
- END IsZero;
- PROCEDURE [stdcall] sqrt* (x: REAL): REAL;
- BEGIN
- SYSTEM.CODE(
- 0DDH, 045H, 008H, (* fld qword [ebp + 08h] *)
- 0D9H, 0FAH, (* fsqrt *)
- 0C9H, (* leave *)
- 0C2H, 008H, 000H (* ret 08h *)
- )
- RETURN 0.0
- END sqrt;
- PROCEDURE [stdcall] sin* (x: REAL): REAL;
- BEGIN
- SYSTEM.CODE(
- 0DDH, 045H, 008H, (* fld qword [ebp + 08h] *)
- 0D9H, 0FEH, (* fsin *)
- 0C9H, (* leave *)
- 0C2H, 008H, 000H (* ret 08h *)
- )
- RETURN 0.0
- END sin;
- PROCEDURE [stdcall] cos* (x: REAL): REAL;
- BEGIN
- SYSTEM.CODE(
- 0DDH, 045H, 008H, (* fld qword [ebp + 08h] *)
- 0D9H, 0FFH, (* fcos *)
- 0C9H, (* leave *)
- 0C2H, 008H, 000H (* ret 08h *)
- )
- RETURN 0.0
- END cos;
- PROCEDURE [stdcall] tan* (x: REAL): REAL;
- BEGIN
- SYSTEM.CODE(
- 0DDH, 045H, 008H, (* fld qword [ebp + 08h] *)
- 0D9H, 0FBH, (* fsincos *)
- 0DEH, 0F9H, (* fdivp st1, st *)
- 0C9H, (* leave *)
- 0C2H, 008H, 000H (* ret 08h *)
- )
- RETURN 0.0
- END tan;
- PROCEDURE [stdcall] arctan2* (y, x: REAL): REAL;
- BEGIN
- SYSTEM.CODE(
- 0DDH, 045H, 008H, (* fld qword [ebp + 08h] *)
- 0DDH, 045H, 010H, (* fld qword [ebp + 10h] *)
- 0D9H, 0F3H, (* fpatan *)
- 0C9H, (* leave *)
- 0C2H, 010H, 000H (* ret 10h *)
- )
- RETURN 0.0
- END arctan2;
- PROCEDURE [stdcall] ln* (x: REAL): REAL;
- BEGIN
- SYSTEM.CODE(
- 0D9H, 0EDH, (* fldln2 *)
- 0DDH, 045H, 008H, (* fld qword [ebp + 08h] *)
- 0D9H, 0F1H, (* fyl2x *)
- 0C9H, (* leave *)
- 0C2H, 008H, 000H (* ret 08h *)
- )
- RETURN 0.0
- END ln;
- PROCEDURE [stdcall] log* (base, x: REAL): REAL;
- BEGIN
- SYSTEM.CODE(
- 0D9H, 0E8H, (* fld1 *)
- 0DDH, 045H, 010H, (* fld qword [ebp + 10h] *)
- 0D9H, 0F1H, (* fyl2x *)
- 0D9H, 0E8H, (* fld1 *)
- 0DDH, 045H, 008H, (* fld qword [ebp + 08h] *)
- 0D9H, 0F1H, (* fyl2x *)
- 0DEH, 0F9H, (* fdivp st1, st *)
- 0C9H, (* leave *)
- 0C2H, 010H, 000H (* ret 10h *)
- )
- RETURN 0.0
- END log;
- PROCEDURE [stdcall] exp* (x: REAL): REAL;
- BEGIN
- SYSTEM.CODE(
- 0DDH, 045H, 008H, (* fld qword [ebp + 08h] *)
- 0D9H, 0EAH, (* fldl2e *)
- 0DEH, 0C9H, 0D9H, 0C0H,
- 0D9H, 0FCH, 0DCH, 0E9H,
- 0D9H, 0C9H, 0D9H, 0F0H,
- 0D9H, 0E8H, 0DEH, 0C1H,
- 0D9H, 0FDH, 0DDH, 0D9H,
- 0C9H, (* leave *)
- 0C2H, 008H, 000H (* ret 08h *)
- )
- RETURN 0.0
- END exp;
- PROCEDURE [stdcall] round* (x: REAL): REAL;
- BEGIN
- SYSTEM.CODE(
- 0DDH, 045H, 008H, (* fld qword [ebp + 08h] *)
- 0D9H, 07DH, 0F4H, 0D9H,
- 07DH, 0F6H, 066H, 081H,
- 04DH, 0F6H, 000H, 003H,
- 0D9H, 06DH, 0F6H, 0D9H,
- 0FCH, 0D9H, 06DH, 0F4H,
- 0C9H, (* leave *)
- 0C2H, 008H, 000H (* ret 08h *)
- )
- RETURN 0.0
- END round;
- PROCEDURE [stdcall] frac* (x: REAL): REAL;
- BEGIN
- SYSTEM.CODE(
- 050H,
- 0DDH, 045H, 008H, (* fld qword [ebp + 08h] *)
- 0D9H, 0C0H, 0D9H, 03CH,
- 024H, 0D9H, 07CH, 024H,
- 002H, 066H, 081H, 04CH,
- 024H, 002H, 000H, 00FH,
- 0D9H, 06CH, 024H, 002H,
- 0D9H, 0FCH, 0D9H, 02CH,
- 024H, 0DEH, 0E9H,
- 0C9H, (* leave *)
- 0C2H, 008H, 000H (* ret 08h *)
- )
- RETURN 0.0
- END frac;
- PROCEDURE sqri* (x: INTEGER): INTEGER;
- RETURN x * x
- END sqri;
- PROCEDURE sqrr* (x: REAL): REAL;
- RETURN x * x
- END sqrr;
- PROCEDURE arcsin* (x: REAL): REAL;
- RETURN arctan2(x, sqrt(1.0 - x * x))
- END arcsin;
- PROCEDURE arccos* (x: REAL): REAL;
- RETURN arctan2(sqrt(1.0 - x * x), x)
- END arccos;
- PROCEDURE arctan* (x: REAL): REAL;
- RETURN arctan2(x, 1.0)
- END arctan;
- PROCEDURE sinh* (x: REAL): REAL;
- BEGIN
- x := exp(x)
- RETURN (x - 1.0 / x) * 0.5
- END sinh;
- PROCEDURE cosh* (x: REAL): REAL;
- BEGIN
- x := exp(x)
- RETURN (x + 1.0 / x) * 0.5
- END cosh;
- PROCEDURE tanh* (x: REAL): REAL;
- BEGIN
- IF x > 15.0 THEN
- x := 1.0
- ELSIF x < -15.0 THEN
- x := -1.0
- ELSE
- x := 1.0 - 2.0 / (exp(2.0 * x) + 1.0)
- END
- RETURN x
- END tanh;
- PROCEDURE arsinh* (x: REAL): REAL;
- RETURN ln(x + sqrt(x * x + 1.0))
- END arsinh;
- PROCEDURE arcosh* (x: REAL): REAL;
- RETURN ln(x + sqrt(x * x - 1.0))
- END arcosh;
- PROCEDURE artanh* (x: REAL): REAL;
- VAR
- res: REAL;
- BEGIN
- IF SameValue(x, 1.0) THEN
- res := SYSTEM.INF()
- ELSIF SameValue(x, -1.0) THEN
- res := -SYSTEM.INF()
- ELSE
- res := 0.5 * ln((1.0 + x) / (1.0 - x))
- END
- RETURN res
- END artanh;
- PROCEDURE floor* (x: REAL): REAL;
- VAR
- f: REAL;
- BEGIN
- f := frac(x);
- x := x - f;
- IF f < 0.0 THEN
- x := x - 1.0
- END
- RETURN x
- END floor;
- PROCEDURE ceil* (x: REAL): REAL;
- VAR
- f: REAL;
- BEGIN
- f := frac(x);
- x := x - f;
- IF f > 0.0 THEN
- x := x + 1.0
- END
- RETURN x
- END ceil;
- PROCEDURE power* (base, exponent: REAL): REAL;
- VAR
- res: REAL;
- BEGIN
- IF exponent = 0.0 THEN
- res := 1.0
- ELSIF (base = 0.0) & (exponent > 0.0) THEN
- res := 0.0
- ELSE
- res := exp(exponent * ln(base))
- END
- RETURN res
- END power;
- PROCEDURE ipower* (base: REAL; exponent: INTEGER): REAL;
- VAR
- i: INTEGER;
- a: REAL;
- BEGIN
- a := 1.0;
- IF base # 0.0 THEN
- IF exponent # 0 THEN
- IF exponent < 0 THEN
- base := 1.0 / base
- END;
- i := ABS(exponent);
- WHILE i > 0 DO
- WHILE ~ODD(i) DO
- i := LSR(i, 1);
- base := sqrr(base)
- END;
- DEC(i);
- a := a * base
- END
- ELSE
- a := 1.0
- END
- ELSE
- ASSERT(exponent > 0);
- a := 0.0
- END
- RETURN a
- END ipower;
- PROCEDURE sgn* (x: REAL): INTEGER;
- VAR
- res: INTEGER;
- BEGIN
- IF x > 0.0 THEN
- res := 1
- ELSIF x < 0.0 THEN
- res := -1
- ELSE
- res := 0
- END
- RETURN res
- END sgn;
- PROCEDURE fact* (n: INTEGER): REAL;
- VAR
- res: REAL;
- BEGIN
- res := 1.0;
- WHILE n > 1 DO
- res := res * FLT(n);
- DEC(n)
- END
- RETURN res
- END fact;
- PROCEDURE DegToRad* (x: REAL): REAL;
- RETURN x * (pi / 180.0)
- END DegToRad;
- PROCEDURE RadToDeg* (x: REAL): REAL;
- RETURN x * (180.0 / pi)
- END RadToDeg;
- (* Return hypotenuse of triangle *)
- PROCEDURE hypot* (x, y: REAL): REAL;
- VAR
- a: REAL;
- BEGIN
- x := ABS(x);
- y := ABS(y);
- IF x > y THEN
- a := x * sqrt(1.0 + sqrr(y / x))
- ELSE
- IF x > 0.0 THEN
- a := y * sqrt(1.0 + sqrr(x / y))
- ELSE
- a := y
- END
- END
- RETURN a
- END hypot;
- END Math.
|