Subversion Repositories Kolibri OS

Rev

Rev 6613 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. (*
  2.     Copyright 2013, 2014, 2018 Anton Krotov
  3.  
  4.     This program is free software: you can redistribute it and/or modify
  5.     it under the terms of the GNU Lesser General Public License as published by
  6.     the Free Software Foundation, either version 3 of the License, or
  7.     (at your option) any later version.
  8.  
  9.     This program is distributed in the hope that it will be useful,
  10.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.     GNU Lesser General Public License for more details.
  13.  
  14.     You should have received a copy of the GNU Lesser General Public License
  15.     along with this program.  If not, see <http://www.gnu.org/licenses/>.
  16. *)
  17.  
  18. MODULE Math;
  19.  
  20. IMPORT SYSTEM;
  21.  
  22.  
  23. CONST
  24.  
  25.     pi* = 3.141592653589793;
  26.     e*  = 2.718281828459045;
  27.  
  28.  
  29. PROCEDURE IsNan* (x: REAL): BOOLEAN;
  30. VAR
  31.     h, l: SET;
  32.  
  33. BEGIN
  34.     SYSTEM.GET(SYSTEM.ADR(x), l);
  35.     SYSTEM.GET(SYSTEM.ADR(x) + 4, h)
  36.     RETURN (h * {20..30} = {20..30}) & ((h * {0..19} # {}) OR (l * {0..31} # {}))
  37. END IsNan;
  38.  
  39.  
  40. PROCEDURE IsInf* (x: REAL): BOOLEAN;
  41.     RETURN ABS(x) = SYSTEM.INF()
  42. END IsInf;
  43.  
  44.  
  45. PROCEDURE Max (a, b: REAL): REAL;
  46. VAR
  47.     res: REAL;
  48.  
  49. BEGIN
  50.     IF a > b THEN
  51.         res := a
  52.     ELSE
  53.         res := b
  54.     END
  55.     RETURN res
  56. END Max;
  57.  
  58.  
  59. PROCEDURE Min (a, b: REAL): REAL;
  60. VAR
  61.     res: REAL;
  62.  
  63. BEGIN
  64.     IF a < b THEN
  65.         res := a
  66.     ELSE
  67.         res := b
  68.     END
  69.     RETURN res
  70. END Min;
  71.  
  72.  
  73. PROCEDURE SameValue (a, b: REAL): BOOLEAN;
  74. VAR
  75.     eps: REAL;
  76.     res: BOOLEAN;
  77.  
  78. BEGIN
  79.     eps := Max(Min(ABS(a), ABS(b)) * 1.0E-12, 1.0E-12);
  80.     IF a > b THEN
  81.         res := (a - b) <= eps
  82.     ELSE
  83.         res := (b - a) <= eps
  84.     END
  85.     RETURN res
  86. END SameValue;
  87.  
  88.  
  89. PROCEDURE IsZero (x: REAL): BOOLEAN;
  90.     RETURN ABS(x) <= 1.0E-12
  91. END IsZero;
  92.  
  93.  
  94. PROCEDURE [stdcall] sqrt* (x: REAL): REAL;
  95. BEGIN
  96.     SYSTEM.CODE(
  97.     0DDH, 045H, 008H,              (*  fld     qword [ebp + 08h]  *)
  98.     0D9H, 0FAH,                    (*  fsqrt                      *)
  99.     0C9H,                          (*  leave                      *)
  100.     0C2H, 008H, 000H               (*  ret     08h                *)
  101.     )
  102.     RETURN 0.0
  103. END sqrt;
  104.  
  105.  
  106. PROCEDURE [stdcall] sin* (x: REAL): REAL;
  107. BEGIN
  108.     SYSTEM.CODE(
  109.     0DDH, 045H, 008H,              (*  fld     qword [ebp + 08h]  *)
  110.     0D9H, 0FEH,                    (*  fsin                       *)
  111.     0C9H,                          (*  leave                      *)
  112.     0C2H, 008H, 000H               (*  ret     08h                *)
  113.     )
  114.     RETURN 0.0
  115. END sin;
  116.  
  117.  
  118. PROCEDURE [stdcall] cos* (x: REAL): REAL;
  119. BEGIN
  120.     SYSTEM.CODE(
  121.     0DDH, 045H, 008H,              (*  fld     qword [ebp + 08h]  *)
  122.     0D9H, 0FFH,                    (*  fcos                       *)
  123.     0C9H,                          (*  leave                      *)
  124.     0C2H, 008H, 000H               (*  ret     08h                *)
  125.     )
  126.     RETURN 0.0
  127. END cos;
  128.  
  129.  
  130. PROCEDURE [stdcall] tan* (x: REAL): REAL;
  131. BEGIN
  132.     SYSTEM.CODE(
  133.     0DDH, 045H, 008H,              (*  fld     qword [ebp + 08h]  *)
  134.     0D9H, 0FBH,                    (*  fsincos                    *)
  135.     0DEH, 0F9H,                    (*  fdivp st1, st              *)
  136.     0C9H,                          (*  leave                      *)
  137.     0C2H, 008H, 000H               (*  ret     08h                *)
  138.     )
  139.     RETURN 0.0
  140. END tan;
  141.  
  142.  
  143. PROCEDURE [stdcall] arctan2* (y, x: REAL): REAL;
  144. BEGIN
  145.     SYSTEM.CODE(
  146.     0DDH, 045H, 008H,              (*  fld     qword [ebp + 08h]  *)
  147.     0DDH, 045H, 010H,              (*  fld     qword [ebp + 10h]  *)
  148.     0D9H, 0F3H,                    (*  fpatan                     *)
  149.     0C9H,                          (*  leave                      *)
  150.     0C2H, 010H, 000H               (*  ret     10h                *)
  151.     )
  152.     RETURN 0.0
  153. END arctan2;
  154.  
  155.  
  156. PROCEDURE [stdcall] ln* (x: REAL): REAL;
  157. BEGIN
  158.     SYSTEM.CODE(
  159.     0D9H, 0EDH,                    (*  fldln2                     *)
  160.     0DDH, 045H, 008H,              (*  fld     qword [ebp + 08h]  *)
  161.     0D9H, 0F1H,                    (*  fyl2x                      *)
  162.     0C9H,                          (*  leave                      *)
  163.     0C2H, 008H, 000H               (*  ret     08h                *)
  164.     )
  165.     RETURN 0.0
  166. END ln;
  167.  
  168.  
  169. PROCEDURE [stdcall] log* (base, x: REAL): REAL;
  170. BEGIN            
  171.     SYSTEM.CODE(
  172.     0D9H, 0E8H,                    (*  fld1                       *)
  173.     0DDH, 045H, 010H,              (*  fld     qword [ebp + 10h]  *)
  174.     0D9H, 0F1H,                    (*  fyl2x                      *)
  175.     0D9H, 0E8H,                    (*  fld1                       *)
  176.     0DDH, 045H, 008H,              (*  fld     qword [ebp + 08h]  *)
  177.     0D9H, 0F1H,                    (*  fyl2x                      *)
  178.     0DEH, 0F9H,                    (*  fdivp st1, st              *)
  179.     0C9H,                          (*  leave                      *)
  180.     0C2H, 010H, 000H               (*  ret     10h                *)
  181.     )
  182.     RETURN 0.0
  183. END log;
  184.  
  185.  
  186. PROCEDURE [stdcall] exp* (x: REAL): REAL;
  187. BEGIN
  188.     SYSTEM.CODE(
  189.     0DDH, 045H, 008H,           (*  fld     qword [ebp + 08h]  *)
  190.     0D9H, 0EAH,                 (*  fldl2e                     *)
  191.     0DEH, 0C9H, 0D9H, 0C0H,
  192.     0D9H, 0FCH, 0DCH, 0E9H,
  193.     0D9H, 0C9H, 0D9H, 0F0H,
  194.     0D9H, 0E8H, 0DEH, 0C1H,
  195.     0D9H, 0FDH, 0DDH, 0D9H,
  196.     0C9H,                       (*  leave                      *)
  197.     0C2H, 008H, 000H            (*  ret     08h                *)
  198.     )
  199.     RETURN 0.0
  200. END exp;
  201.  
  202.  
  203. PROCEDURE [stdcall] round* (x: REAL): REAL;
  204. BEGIN
  205.     SYSTEM.CODE(
  206.     0DDH, 045H, 008H,           (*  fld     qword [ebp + 08h]  *)
  207.     0D9H, 07DH, 0F4H, 0D9H,
  208.     07DH, 0F6H, 066H, 081H,
  209.     04DH, 0F6H, 000H, 003H,
  210.     0D9H, 06DH, 0F6H, 0D9H,
  211.     0FCH, 0D9H, 06DH, 0F4H,
  212.     0C9H,                       (*  leave                     *)
  213.     0C2H, 008H, 000H            (*  ret     08h               *)
  214.     )
  215.     RETURN 0.0
  216. END round;
  217.  
  218.  
  219. PROCEDURE [stdcall] frac* (x: REAL): REAL;
  220. BEGIN
  221.     SYSTEM.CODE(
  222.     050H,
  223.     0DDH, 045H, 008H,           (*  fld     qword [ebp + 08h]  *)
  224.     0D9H, 0C0H, 0D9H, 03CH,
  225.     024H, 0D9H, 07CH, 024H,
  226.     002H, 066H, 081H, 04CH,
  227.     024H, 002H, 000H, 00FH,
  228.     0D9H, 06CH, 024H, 002H,
  229.     0D9H, 0FCH, 0D9H, 02CH,
  230.     024H, 0DEH, 0E9H,
  231.     0C9H,                       (*  leave                     *)
  232.     0C2H, 008H, 000H            (*  ret     08h               *)
  233.     )
  234.     RETURN 0.0
  235. END frac;
  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. VAR
  255.     res: REAL;
  256.  
  257. BEGIN
  258.     IF IsZero(x) THEN
  259.         res := 0.0
  260.     ELSE
  261.         res := (exp(x) - exp(-x)) / 2.0
  262.     END
  263.     RETURN res
  264. END sinh;
  265.  
  266.  
  267. PROCEDURE cosh* (x: REAL): REAL;
  268. VAR
  269.     res: REAL;
  270.  
  271. BEGIN
  272.     IF IsZero(x) THEN
  273.         res := 1.0
  274.     ELSE
  275.         res := (exp(x) + exp(-x)) / 2.0
  276.     END
  277.     RETURN res
  278. END cosh;
  279.  
  280.  
  281. PROCEDURE tanh* (x: REAL): REAL;
  282. VAR
  283.     res: REAL;
  284.  
  285. BEGIN
  286.     IF IsZero(x) THEN
  287.         res := 0.0
  288.     ELSE
  289.         res := sinh(x) / cosh(x)
  290.     END
  291.     RETURN res
  292. END tanh;
  293.  
  294.  
  295. PROCEDURE arcsinh* (x: REAL): REAL;
  296.     RETURN ln(x + sqrt((x * x) + 1.0))
  297. END arcsinh;
  298.  
  299.  
  300. PROCEDURE arccosh* (x: REAL): REAL;
  301.     RETURN ln(x + sqrt((x - 1.0) / (x + 1.0)) * (x + 1.0))
  302. END arccosh;
  303.  
  304.  
  305. PROCEDURE arctanh* (x: REAL): REAL;
  306. VAR
  307.     res: REAL;
  308.  
  309. BEGIN
  310.     IF SameValue(x, 1.0) THEN
  311.         res := SYSTEM.INF()
  312.     ELSIF SameValue(x, -1.0) THEN
  313.         res := -SYSTEM.INF()
  314.     ELSE
  315.         res := 0.5 * ln((1.0 + x) / (1.0 - x))
  316.     END
  317.     RETURN res
  318. END arctanh;
  319.  
  320.  
  321. PROCEDURE floor* (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 floor;
  333.  
  334.  
  335. PROCEDURE ceil* (x: REAL): REAL;
  336. VAR
  337.     f: REAL;
  338.  
  339. BEGIN
  340.     f := frac(x);
  341.     x := x - f;
  342.     IF f > 0.0 THEN
  343.         x := x + 1.0
  344.     END
  345.     RETURN x
  346. END ceil;
  347.  
  348.  
  349. PROCEDURE power* (base, exponent: REAL): REAL;
  350. VAR
  351.     res: REAL;
  352.  
  353. BEGIN
  354.     IF exponent = 0.0 THEN
  355.         res := 1.0
  356.     ELSIF (base = 0.0) & (exponent > 0.0) THEN
  357.         res := 0.0
  358.     ELSE
  359.         res := exp(exponent * ln(base))
  360.     END
  361.     RETURN res
  362. END power;
  363.  
  364.  
  365. PROCEDURE sgn* (x: REAL): INTEGER;
  366. VAR
  367.     res: INTEGER;
  368.  
  369. BEGIN
  370.     IF x > 0.0 THEN
  371.         res := 1
  372.     ELSIF x < 0.0 THEN
  373.         res := -1
  374.     ELSE
  375.         res := 0
  376.     END
  377.     RETURN res
  378. END sgn;
  379.          
  380.  
  381. END Math.