Subversion Repositories Kolibri OS

Rev

Rev 7597 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
7597 akron1 1
(*
7693 akron1 2
    Copyright 2013, 2014, 2018, 2019 Anton Krotov
6613 leency 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 .
16
*)
17
 
18
MODULE Math;
19
 
7597 akron1 20
IMPORT SYSTEM;
6613 leency 21
 
22
 
7597 akron1 23
CONST
6613 leency 24
 
7597 akron1 25
    pi* = 3.141592653589793;
26
    e*  = 2.718281828459045;
27
 
28
 
29
PROCEDURE IsNan* (x: REAL): BOOLEAN;
30
VAR
31
    h, l: SET;
32
 
6613 leency 33
BEGIN
7597 akron1 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} # {}))
6613 leency 37
END IsNan;
38
 
7597 akron1 39
 
40
PROCEDURE IsInf* (x: REAL): BOOLEAN;
41
    RETURN ABS(x) = SYSTEM.INF()
6613 leency 42
END IsInf;
43
 
7597 akron1 44
 
45
PROCEDURE Max (a, b: REAL): REAL;
46
VAR
47
    res: REAL;
48
 
6613 leency 49
BEGIN
7597 akron1 50
    IF a > b THEN
51
        res := a
52
    ELSE
53
        res := b
54
    END
55
    RETURN res
6613 leency 56
END Max;
57
 
7597 akron1 58
 
59
PROCEDURE Min (a, b: REAL): REAL;
60
VAR
61
    res: REAL;
62
 
6613 leency 63
BEGIN
7597 akron1 64
    IF a < b THEN
65
        res := a
66
    ELSE
67
        res := b
68
    END
69
    RETURN res
6613 leency 70
END Min;
71
 
7597 akron1 72
 
73
PROCEDURE SameValue (a, b: REAL): BOOLEAN;
74
VAR
75
    eps: REAL;
76
    res: BOOLEAN;
77
 
6613 leency 78
BEGIN
7597 akron1 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
6613 leency 86
END SameValue;
87
 
7597 akron1 88
 
89
PROCEDURE IsZero (x: REAL): BOOLEAN;
90
    RETURN ABS(x) <= 1.0E-12
6613 leency 91
END IsZero;
92
 
7597 akron1 93
 
94
PROCEDURE [stdcall] sqrt* (x: REAL): REAL;
6613 leency 95
BEGIN
7597 akron1 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
6613 leency 103
END sqrt;
104
 
7597 akron1 105
 
106
PROCEDURE [stdcall] sin* (x: REAL): REAL;
6613 leency 107
BEGIN
7597 akron1 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
6613 leency 115
END sin;
116
 
7597 akron1 117
 
118
PROCEDURE [stdcall] cos* (x: REAL): REAL;
6613 leency 119
BEGIN
7597 akron1 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
6613 leency 127
END cos;
128
 
7597 akron1 129
 
130
PROCEDURE [stdcall] tan* (x: REAL): REAL;
6613 leency 131
BEGIN
7597 akron1 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
6613 leency 140
END tan;
141
 
7597 akron1 142
 
143
PROCEDURE [stdcall] arctan2* (y, x: REAL): REAL;
6613 leency 144
BEGIN
7597 akron1 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
6613 leency 153
END arctan2;
154
 
7597 akron1 155
 
156
PROCEDURE [stdcall] ln* (x: REAL): REAL;
6613 leency 157
BEGIN
7597 akron1 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
6613 leency 166
END ln;
167
 
7597 akron1 168
 
169
PROCEDURE [stdcall] log* (base, x: REAL): REAL;
7693 akron1 170
BEGIN
7597 akron1 171
    SYSTEM.CODE(
172
    0D9H, 0E8H,                    (*  fld1                       *)
7693 akron1 173
    0DDH, 045H, 010H,              (*  fld     qword [ebp + 10h]  *)
7597 akron1 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
6613 leency 183
END log;
184
 
7597 akron1 185
 
186
PROCEDURE [stdcall] exp* (x: REAL): REAL;
6613 leency 187
BEGIN
7597 akron1 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
6613 leency 200
END exp;
201
 
7597 akron1 202
 
203
PROCEDURE [stdcall] round* (x: REAL): REAL;
6613 leency 204
BEGIN
7597 akron1 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
6613 leency 216
END round;
217
 
7597 akron1 218
 
219
PROCEDURE [stdcall] frac* (x: REAL): REAL;
6613 leency 220
BEGIN
7597 akron1 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
6613 leency 235
END frac;
236
 
7597 akron1 237
 
238
PROCEDURE arcsin* (x: REAL): REAL;
239
    RETURN arctan2(x, sqrt(1.0 - x * x))
6613 leency 240
END arcsin;
241
 
7597 akron1 242
 
243
PROCEDURE arccos* (x: REAL): REAL;
244
    RETURN arctan2(sqrt(1.0 - x * x), x)
6613 leency 245
END arccos;
246
 
7597 akron1 247
 
248
PROCEDURE arctan* (x: REAL): REAL;
249
    RETURN arctan2(x, 1.0)
6613 leency 250
END arctan;
251
 
7597 akron1 252
 
253
PROCEDURE sinh* (x: REAL): REAL;
6613 leency 254
BEGIN
7693 akron1 255
    x := exp(x)
256
    RETURN (x - 1.0 / x) * 0.5
6613 leency 257
END sinh;
258
 
7597 akron1 259
 
260
PROCEDURE cosh* (x: REAL): REAL;
6613 leency 261
BEGIN
7693 akron1 262
    x := exp(x)
263
    RETURN (x + 1.0 / x) * 0.5
6613 leency 264
END cosh;
265
 
7597 akron1 266
 
267
PROCEDURE tanh* (x: REAL): REAL;
6613 leency 268
BEGIN
7693 akron1 269
    IF x > 15.0 THEN
270
        x := 1.0
271
    ELSIF x < -15.0 THEN
272
        x := -1.0
7597 akron1 273
    ELSE
7693 akron1 274
        x := exp(2.0 * x);
275
        x := (x - 1.0) / (x + 1.0)
7597 akron1 276
    END
7693 akron1 277
 
278
    RETURN x
6613 leency 279
END tanh;
280
 
7597 akron1 281
 
7693 akron1 282
PROCEDURE arsinh* (x: REAL): REAL;
283
    RETURN ln(x + sqrt(x * x + 1.0))
284
END arsinh;
6613 leency 285
 
7597 akron1 286
 
7693 akron1 287
PROCEDURE arcosh* (x: REAL): REAL;
288
    RETURN ln(x + sqrt(x * x - 1.0))
289
END arcosh;
6613 leency 290
 
7597 akron1 291
 
7693 akron1 292
PROCEDURE artanh* (x: REAL): REAL;
7597 akron1 293
VAR
294
    res: REAL;
295
 
6613 leency 296
BEGIN
7597 akron1 297
    IF SameValue(x, 1.0) THEN
298
        res := SYSTEM.INF()
299
    ELSIF SameValue(x, -1.0) THEN
300
        res := -SYSTEM.INF()
301
    ELSE
302
        res := 0.5 * ln((1.0 + x) / (1.0 - x))
303
    END
304
    RETURN res
7693 akron1 305
END artanh;
6613 leency 306
 
7597 akron1 307
 
308
PROCEDURE floor* (x: REAL): REAL;
309
VAR
310
    f: REAL;
311
 
6613 leency 312
BEGIN
7597 akron1 313
    f := frac(x);
314
    x := x - f;
315
    IF f < 0.0 THEN
316
        x := x - 1.0
317
    END
318
    RETURN x
6613 leency 319
END floor;
320
 
7597 akron1 321
 
322
PROCEDURE ceil* (x: REAL): REAL;
323
VAR
324
    f: REAL;
325
 
6613 leency 326
BEGIN
7597 akron1 327
    f := frac(x);
328
    x := x - f;
329
    IF f > 0.0 THEN
330
        x := x + 1.0
331
    END
332
    RETURN x
6613 leency 333
END ceil;
334
 
7597 akron1 335
 
336
PROCEDURE power* (base, exponent: REAL): REAL;
337
VAR
338
    res: REAL;
339
 
6613 leency 340
BEGIN
7597 akron1 341
    IF exponent = 0.0 THEN
342
        res := 1.0
343
    ELSIF (base = 0.0) & (exponent > 0.0) THEN
344
        res := 0.0
345
    ELSE
346
        res := exp(exponent * ln(base))
347
    END
348
    RETURN res
6613 leency 349
END power;
350
 
7597 akron1 351
 
352
PROCEDURE sgn* (x: REAL): INTEGER;
353
VAR
354
    res: INTEGER;
355
 
6613 leency 356
BEGIN
7597 akron1 357
    IF x > 0.0 THEN
358
        res := 1
359
    ELSIF x < 0.0 THEN
360
        res := -1
361
    ELSE
362
        res := 0
363
    END
7693 akron1 364
 
7597 akron1 365
    RETURN res
6613 leency 366
END sgn;
367
 
7693 akron1 368
 
369
PROCEDURE fact* (n: INTEGER): REAL;
370
VAR
371
    res: REAL;
372
 
373
BEGIN
374
    res := 1.0;
375
    WHILE n > 1 DO
376
        res := res * FLT(n);
377
        DEC(n)
378
    END
379
 
380
    RETURN res
381
END fact;
382
 
383
 
6613 leency 384
END Math.