Subversion Repositories Kolibri OS

Rev

Rev 8859 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. (*
  2.     BSD 2-Clause License
  3.  
  4.     Copyright (c) 2013-2014, 2018-2022 Anton Krotov
  5.     All rights reserved.
  6. *)
  7.  
  8. MODULE Math;
  9.  
  10. IMPORT SYSTEM;
  11.  
  12.  
  13. CONST
  14.  
  15.     pi* = 3.141592653589793;
  16.     e*  = 2.718281828459045;
  17.  
  18.  
  19. PROCEDURE IsNan* (x: REAL): BOOLEAN;
  20. VAR
  21.     h, l: SET;
  22.  
  23. BEGIN
  24.     SYSTEM.GET(SYSTEM.ADR(x), l);
  25.     SYSTEM.GET(SYSTEM.ADR(x) + 4, h)
  26.     RETURN (h * {20..30} = {20..30}) & ((h * {0..19} # {}) OR (l * {0..31} # {}))
  27. END IsNan;
  28.  
  29.  
  30. PROCEDURE IsInf* (x: REAL): BOOLEAN;
  31.     RETURN ABS(x) = SYSTEM.INF()
  32. END IsInf;
  33.  
  34.  
  35. PROCEDURE Max (a, b: REAL): REAL;
  36. VAR
  37.     res: REAL;
  38.  
  39. BEGIN
  40.     IF a > b THEN
  41.         res := a
  42.     ELSE
  43.         res := b
  44.     END
  45.     RETURN res
  46. END Max;
  47.  
  48.  
  49. PROCEDURE Min (a, b: REAL): REAL;
  50. VAR
  51.     res: REAL;
  52.  
  53. BEGIN
  54.     IF a < b THEN
  55.         res := a
  56.     ELSE
  57.         res := b
  58.     END
  59.     RETURN res
  60. END Min;
  61.  
  62.  
  63. PROCEDURE SameValue (a, b: REAL): BOOLEAN;
  64. VAR
  65.     eps: REAL;
  66.     res: BOOLEAN;
  67.  
  68. BEGIN
  69.     eps := Max(Min(ABS(a), ABS(b)) * 1.0E-12, 1.0E-12);
  70.     IF a > b THEN
  71.         res := (a - b) <= eps
  72.     ELSE
  73.         res := (b - a) <= eps
  74.     END
  75.     RETURN res
  76. END SameValue;
  77.  
  78.  
  79. PROCEDURE IsZero (x: REAL): BOOLEAN;
  80.     RETURN ABS(x) <= 1.0E-12
  81. END IsZero;
  82.  
  83.  
  84. PROCEDURE [stdcall] sqrt* (x: REAL): REAL;
  85. BEGIN
  86.     SYSTEM.CODE(
  87.     0DDH, 045H, 008H,              (*  fld     qword [ebp + 08h]  *)
  88.     0D9H, 0FAH,                    (*  fsqrt                      *)
  89.     0C9H,                          (*  leave                      *)
  90.     0C2H, 008H, 000H               (*  ret     08h                *)
  91.     )
  92.     RETURN 0.0
  93. END sqrt;
  94.  
  95.  
  96. PROCEDURE [stdcall] sin* (x: REAL): REAL;
  97. BEGIN
  98.     SYSTEM.CODE(
  99.     0DDH, 045H, 008H,              (*  fld     qword [ebp + 08h]  *)
  100.     0D9H, 0FEH,                    (*  fsin                       *)
  101.     0C9H,                          (*  leave                      *)
  102.     0C2H, 008H, 000H               (*  ret     08h                *)
  103.     )
  104.     RETURN 0.0
  105. END sin;
  106.  
  107.  
  108. PROCEDURE [stdcall] cos* (x: REAL): REAL;
  109. BEGIN
  110.     SYSTEM.CODE(
  111.     0DDH, 045H, 008H,              (*  fld     qword [ebp + 08h]  *)
  112.     0D9H, 0FFH,                    (*  fcos                       *)
  113.     0C9H,                          (*  leave                      *)
  114.     0C2H, 008H, 000H               (*  ret     08h                *)
  115.     )
  116.     RETURN 0.0
  117. END cos;
  118.  
  119.  
  120. PROCEDURE [stdcall] tan* (x: REAL): REAL;
  121. BEGIN
  122.     SYSTEM.CODE(
  123.     0DDH, 045H, 008H,              (*  fld     qword [ebp + 08h]  *)
  124.     0D9H, 0FBH,                    (*  fsincos                    *)
  125.     0DEH, 0F9H,                    (*  fdivp st1, st              *)
  126.     0C9H,                          (*  leave                      *)
  127.     0C2H, 008H, 000H               (*  ret     08h                *)
  128.     )
  129.     RETURN 0.0
  130. END tan;
  131.  
  132.  
  133. PROCEDURE [stdcall] arctan2* (y, x: REAL): REAL;
  134. BEGIN
  135.     SYSTEM.CODE(
  136.     0DDH, 045H, 008H,              (*  fld     qword [ebp + 08h]  *)
  137.     0DDH, 045H, 010H,              (*  fld     qword [ebp + 10h]  *)
  138.     0D9H, 0F3H,                    (*  fpatan                     *)
  139.     0C9H,                          (*  leave                      *)
  140.     0C2H, 010H, 000H               (*  ret     10h                *)
  141.     )
  142.     RETURN 0.0
  143. END arctan2;
  144.  
  145.  
  146. PROCEDURE [stdcall] ln* (x: REAL): REAL;
  147. BEGIN
  148.     SYSTEM.CODE(
  149.     0D9H, 0EDH,                    (*  fldln2                     *)
  150.     0DDH, 045H, 008H,              (*  fld     qword [ebp + 08h]  *)
  151.     0D9H, 0F1H,                    (*  fyl2x                      *)
  152.     0C9H,                          (*  leave                      *)
  153.     0C2H, 008H, 000H               (*  ret     08h                *)
  154.     )
  155.     RETURN 0.0
  156. END ln;
  157.  
  158.  
  159. PROCEDURE [stdcall] log* (base, x: REAL): REAL;
  160. BEGIN
  161.     SYSTEM.CODE(
  162.     0D9H, 0E8H,                    (*  fld1                       *)
  163.     0DDH, 045H, 010H,              (*  fld     qword [ebp + 10h]  *)
  164.     0D9H, 0F1H,                    (*  fyl2x                      *)
  165.     0D9H, 0E8H,                    (*  fld1                       *)
  166.     0DDH, 045H, 008H,              (*  fld     qword [ebp + 08h]  *)
  167.     0D9H, 0F1H,                    (*  fyl2x                      *)
  168.     0DEH, 0F9H,                    (*  fdivp st1, st              *)
  169.     0C9H,                          (*  leave                      *)
  170.     0C2H, 010H, 000H               (*  ret     10h                *)
  171.     )
  172.     RETURN 0.0
  173. END log;
  174.  
  175.  
  176. PROCEDURE [stdcall] exp* (x: REAL): REAL;
  177. BEGIN
  178.     SYSTEM.CODE(
  179.     0DDH, 045H, 008H,           (*  fld     qword [ebp + 08h]  *)
  180.     0D9H, 0EAH,                 (*  fldl2e                     *)
  181.     0DEH, 0C9H, 0D9H, 0C0H,
  182.     0D9H, 0FCH, 0DCH, 0E9H,
  183.     0D9H, 0C9H, 0D9H, 0F0H,
  184.     0D9H, 0E8H, 0DEH, 0C1H,
  185.     0D9H, 0FDH, 0DDH, 0D9H,
  186.     0C9H,                       (*  leave                      *)
  187.     0C2H, 008H, 000H            (*  ret     08h                *)
  188.     )
  189.     RETURN 0.0
  190. END exp;
  191.  
  192.  
  193. PROCEDURE [stdcall] round* (x: REAL): REAL;
  194. BEGIN
  195.     SYSTEM.CODE(
  196.     0DDH, 045H, 008H,           (*  fld     qword [ebp + 08h]  *)
  197.     0D9H, 07DH, 0F4H, 0D9H,
  198.     07DH, 0F6H, 066H, 081H,
  199.     04DH, 0F6H, 000H, 003H,
  200.     0D9H, 06DH, 0F6H, 0D9H,
  201.     0FCH, 0D9H, 06DH, 0F4H,
  202.     0C9H,                       (*  leave                     *)
  203.     0C2H, 008H, 000H            (*  ret     08h               *)
  204.     )
  205.     RETURN 0.0
  206. END round;
  207.  
  208.  
  209. PROCEDURE [stdcall] frac* (x: REAL): REAL;
  210. BEGIN
  211.     SYSTEM.CODE(
  212.     050H,
  213.     0DDH, 045H, 008H,           (*  fld     qword [ebp + 08h]  *)
  214.     0D9H, 0C0H, 0D9H, 03CH,
  215.     024H, 0D9H, 07CH, 024H,
  216.     002H, 066H, 081H, 04CH,
  217.     024H, 002H, 000H, 00FH,
  218.     0D9H, 06CH, 024H, 002H,
  219.     0D9H, 0FCH, 0D9H, 02CH,
  220.     024H, 0DEH, 0E9H,
  221.     0C9H,                       (*  leave                     *)
  222.     0C2H, 008H, 000H            (*  ret     08h               *)
  223.     )
  224.     RETURN 0.0
  225. END frac;
  226.  
  227.  
  228. PROCEDURE sqri* (x: INTEGER): INTEGER;
  229.     RETURN x * x
  230. END sqri;
  231.  
  232.  
  233. PROCEDURE sqrr* (x: REAL): REAL;
  234.     RETURN x * x
  235. END sqrr;
  236.  
  237.  
  238. PROCEDURE arcsin* (x: REAL): REAL;
  239.     RETURN arctan2(x, sqrt(1.0 - x * x))
  240. END arcsin;
  241.  
  242.  
  243. PROCEDURE arccos* (x: REAL): REAL;
  244.     RETURN arctan2(sqrt(1.0 - x * x), x)
  245. END arccos;
  246.  
  247.  
  248. PROCEDURE arctan* (x: REAL): REAL;
  249.     RETURN arctan2(x, 1.0)
  250. END arctan;
  251.  
  252.  
  253. PROCEDURE sinh* (x: REAL): REAL;
  254. BEGIN
  255.     x := exp(x)
  256.     RETURN (x - 1.0 / x) * 0.5
  257. END sinh;
  258.  
  259.  
  260. PROCEDURE cosh* (x: REAL): REAL;
  261. BEGIN
  262.     x := exp(x)
  263.     RETURN (x + 1.0 / x) * 0.5
  264. END cosh;
  265.  
  266.  
  267. PROCEDURE tanh* (x: REAL): REAL;
  268. BEGIN
  269.     IF x > 15.0 THEN
  270.         x := 1.0
  271.     ELSIF x < -15.0 THEN
  272.         x := -1.0
  273.     ELSE
  274.         x := 1.0 - 2.0 / (exp(2.0 * x) + 1.0)
  275.     END
  276.  
  277.     RETURN x
  278. END tanh;
  279.  
  280.  
  281. PROCEDURE arsinh* (x: REAL): REAL;
  282.     RETURN ln(x + sqrt(x * x + 1.0))
  283. END arsinh;
  284.  
  285.  
  286. PROCEDURE arcosh* (x: REAL): REAL;
  287.     RETURN ln(x + sqrt(x * x - 1.0))
  288. END arcosh;
  289.  
  290.  
  291. PROCEDURE artanh* (x: REAL): REAL;
  292. VAR
  293.     res: REAL;
  294.  
  295. BEGIN
  296.     IF SameValue(x, 1.0) THEN
  297.         res := SYSTEM.INF()
  298.     ELSIF SameValue(x, -1.0) THEN
  299.         res := -SYSTEM.INF()
  300.     ELSE
  301.         res := 0.5 * ln((1.0 + x) / (1.0 - x))
  302.     END
  303.     RETURN res
  304. END artanh;
  305.  
  306.  
  307. PROCEDURE floor* (x: REAL): REAL;
  308. VAR
  309.     f: REAL;
  310.  
  311. BEGIN
  312.     f := frac(x);
  313.     x := x - f;
  314.     IF f < 0.0 THEN
  315.         x := x - 1.0
  316.     END
  317.     RETURN x
  318. END floor;
  319.  
  320.  
  321. PROCEDURE ceil* (x: REAL): REAL;
  322. VAR
  323.     f: REAL;
  324.  
  325. BEGIN
  326.     f := frac(x);
  327.     x := x - f;
  328.     IF f > 0.0 THEN
  329.         x := x + 1.0
  330.     END
  331.     RETURN x
  332. END ceil;
  333.  
  334.  
  335. PROCEDURE power* (base, exponent: REAL): REAL;
  336. VAR
  337.     res: REAL;
  338.  
  339. BEGIN
  340.     IF exponent = 0.0 THEN
  341.         res := 1.0
  342.     ELSIF (base = 0.0) & (exponent > 0.0) THEN
  343.         res := 0.0
  344.     ELSE
  345.         res := exp(exponent * ln(base))
  346.     END
  347.     RETURN res
  348. END power;
  349.  
  350.  
  351. PROCEDURE ipower* (base: REAL; exponent: INTEGER): REAL;
  352. VAR
  353.     i: INTEGER;
  354.     a: REAL;
  355.  
  356. BEGIN
  357.     a := 1.0;
  358.  
  359.     IF base # 0.0 THEN
  360.         IF exponent # 0 THEN
  361.             IF exponent < 0 THEN
  362.                 base := 1.0 / base
  363.             END;
  364.             i := ABS(exponent);
  365.             WHILE i > 0 DO
  366.                 WHILE ~ODD(i) DO
  367.                     i := LSR(i, 1);
  368.                     base := sqrr(base)
  369.                 END;
  370.                 DEC(i);
  371.                 a := a * base
  372.             END
  373.         ELSE
  374.             a := 1.0
  375.         END
  376.     ELSE
  377.         ASSERT(exponent > 0);
  378.         a := 0.0
  379.     END
  380.  
  381.     RETURN a
  382. END ipower;
  383.  
  384.  
  385. PROCEDURE sgn* (x: REAL): INTEGER;
  386. VAR
  387.     res: INTEGER;
  388.  
  389. BEGIN
  390.     IF x > 0.0 THEN
  391.         res := 1
  392.     ELSIF x < 0.0 THEN
  393.         res := -1
  394.     ELSE
  395.         res := 0
  396.     END
  397.  
  398.     RETURN res
  399. END sgn;
  400.  
  401.  
  402. PROCEDURE fact* (n: INTEGER): REAL;
  403. VAR
  404.     res: REAL;
  405.  
  406. BEGIN
  407.     res := 1.0;
  408.     WHILE n > 1 DO
  409.         res := res * FLT(n);
  410.         DEC(n)
  411.     END
  412.  
  413.     RETURN res
  414. END fact;
  415.  
  416.  
  417. PROCEDURE DegToRad* (x: REAL): REAL;
  418.     RETURN x * (pi / 180.0)
  419. END DegToRad;
  420.  
  421.  
  422. PROCEDURE RadToDeg* (x: REAL): REAL;
  423.     RETURN x * (180.0 / pi)
  424. END RadToDeg;
  425.  
  426.  
  427. (* Return hypotenuse of triangle *)
  428. PROCEDURE hypot* (x, y: REAL): REAL;
  429. VAR
  430.     a: REAL;
  431.  
  432. BEGIN
  433.     x := ABS(x);
  434.     y := ABS(y);
  435.     IF x > y THEN
  436.         a := x * sqrt(1.0 + sqrr(y / x))
  437.     ELSE
  438.         IF x > 0.0 THEN
  439.             a := y * sqrt(1.0 + sqrr(x / y))
  440.         ELSE
  441.             a := y
  442.         END
  443.     END
  444.  
  445.     RETURN a
  446. END hypot;
  447.  
  448.  
  449. END Math.