Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
7983 leency 1
(*
8097 maxcodehac 2
    BSD 2-Clause License
6613 leency 3
 
8097 maxcodehac 4
    Copyright (c) 2013-2014, 2018-2020 Anton Krotov
5
    All rights reserved.
6613 leency 6
*)
7
 
8
MODULE Math;
9
 
7597 akron1 10
IMPORT SYSTEM;
6613 leency 11
 
12
 
7597 akron1 13
CONST
6613 leency 14
 
7597 akron1 15
    pi* = 3.141592653589793;
16
    e*  = 2.718281828459045;
17
 
18
 
19
PROCEDURE IsNan* (x: REAL): BOOLEAN;
20
VAR
21
    h, l: SET;
22
 
6613 leency 23
BEGIN
7597 akron1 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} # {}))
6613 leency 27
END IsNan;
28
 
7597 akron1 29
 
30
PROCEDURE IsInf* (x: REAL): BOOLEAN;
31
    RETURN ABS(x) = SYSTEM.INF()
6613 leency 32
END IsInf;
33
 
7597 akron1 34
 
35
PROCEDURE Max (a, b: REAL): REAL;
36
VAR
37
    res: REAL;
38
 
6613 leency 39
BEGIN
7597 akron1 40
    IF a > b THEN
41
        res := a
42
    ELSE
43
        res := b
44
    END
45
    RETURN res
6613 leency 46
END Max;
47
 
7597 akron1 48
 
49
PROCEDURE Min (a, b: REAL): REAL;
50
VAR
51
    res: REAL;
52
 
6613 leency 53
BEGIN
7597 akron1 54
    IF a < b THEN
55
        res := a
56
    ELSE
57
        res := b
58
    END
59
    RETURN res
6613 leency 60
END Min;
61
 
7597 akron1 62
 
63
PROCEDURE SameValue (a, b: REAL): BOOLEAN;
64
VAR
65
    eps: REAL;
66
    res: BOOLEAN;
67
 
6613 leency 68
BEGIN
7597 akron1 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
6613 leency 76
END SameValue;
77
 
7597 akron1 78
 
79
PROCEDURE IsZero (x: REAL): BOOLEAN;
80
    RETURN ABS(x) <= 1.0E-12
6613 leency 81
END IsZero;
82
 
7597 akron1 83
 
84
PROCEDURE [stdcall] sqrt* (x: REAL): REAL;
6613 leency 85
BEGIN
7597 akron1 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
6613 leency 93
END sqrt;
94
 
7597 akron1 95
 
96
PROCEDURE [stdcall] sin* (x: REAL): REAL;
6613 leency 97
BEGIN
7597 akron1 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
6613 leency 105
END sin;
106
 
7597 akron1 107
 
108
PROCEDURE [stdcall] cos* (x: REAL): REAL;
6613 leency 109
BEGIN
7597 akron1 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
6613 leency 117
END cos;
118
 
7597 akron1 119
 
120
PROCEDURE [stdcall] tan* (x: REAL): REAL;
6613 leency 121
BEGIN
7597 akron1 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
6613 leency 130
END tan;
131
 
7597 akron1 132
 
133
PROCEDURE [stdcall] arctan2* (y, x: REAL): REAL;
6613 leency 134
BEGIN
7597 akron1 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
6613 leency 143
END arctan2;
144
 
7597 akron1 145
 
146
PROCEDURE [stdcall] ln* (x: REAL): REAL;
6613 leency 147
BEGIN
7597 akron1 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
6613 leency 156
END ln;
157
 
7597 akron1 158
 
159
PROCEDURE [stdcall] log* (base, x: REAL): REAL;
7693 akron1 160
BEGIN
7597 akron1 161
    SYSTEM.CODE(
162
    0D9H, 0E8H,                    (*  fld1                       *)
7693 akron1 163
    0DDH, 045H, 010H,              (*  fld     qword [ebp + 10h]  *)
7597 akron1 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
6613 leency 173
END log;
174
 
7597 akron1 175
 
176
PROCEDURE [stdcall] exp* (x: REAL): REAL;
6613 leency 177
BEGIN
7597 akron1 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
6613 leency 190
END exp;
191
 
7597 akron1 192
 
193
PROCEDURE [stdcall] round* (x: REAL): REAL;
6613 leency 194
BEGIN
7597 akron1 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
6613 leency 206
END round;
207
 
7597 akron1 208
 
209
PROCEDURE [stdcall] frac* (x: REAL): REAL;
6613 leency 210
BEGIN
7597 akron1 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
6613 leency 225
END frac;
226
 
7597 akron1 227
 
8097 maxcodehac 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
 
7597 akron1 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
 
8097 maxcodehac 352
PROCEDURE ipower* (base: REAL; exponent: INTEGER): REAL;
353
VAR
354
    i: INTEGER;
355
    a: REAL;
356
 
357
BEGIN
358
    a := 1.0;
359
 
360
    IF base # 0.0 THEN
361
        IF exponent # 0 THEN
362
            IF exponent < 0 THEN
363
                base := 1.0 / base
364
            END;
365
            i := ABS(exponent);
366
            WHILE i > 0 DO
367
                WHILE ~ODD(i) DO
368
                    i := LSR(i, 1);
369
                    base := sqrr(base)
370
                END;
371
                DEC(i);
372
                a := a * base
373
            END
374
        ELSE
375
            a := 1.0
376
        END
377
    ELSE
378
        ASSERT(exponent > 0);
379
        a := 0.0
380
    END
381
 
382
    RETURN a
383
END ipower;
384
 
385
 
7597 akron1 386
PROCEDURE sgn* (x: REAL): INTEGER;
387
VAR
388
    res: INTEGER;
389
 
6613 leency 390
BEGIN
7597 akron1 391
    IF x > 0.0 THEN
392
        res := 1
393
    ELSIF x < 0.0 THEN
394
        res := -1
395
    ELSE
396
        res := 0
397
    END
7693 akron1 398
 
7597 akron1 399
    RETURN res
6613 leency 400
END sgn;
401
 
7693 akron1 402
 
403
PROCEDURE fact* (n: INTEGER): REAL;
404
VAR
405
    res: REAL;
406
 
407
BEGIN
408
    res := 1.0;
409
    WHILE n > 1 DO
410
        res := res * FLT(n);
411
        DEC(n)
412
    END
413
 
414
    RETURN res
415
END fact;
416
 
417
 
8097 maxcodehac 418
PROCEDURE DegToRad* (x: REAL): REAL;
419
    RETURN x * (pi / 180.0)
420
END DegToRad;
421
 
422
 
423
PROCEDURE RadToDeg* (x: REAL): REAL;
424
    RETURN x * (180.0 / pi)
425
END RadToDeg;
426
 
427
 
428
(* Return hypotenuse of triangle *)
429
PROCEDURE hypot* (x, y: REAL): REAL;
430
VAR
431
    a: REAL;
432
 
433
BEGIN
434
    x := ABS(x);
435
    y := ABS(y);
436
    IF x > y THEN
437
        a := x * sqrt(1.0 + sqrr(y / x))
438
    ELSE
439
        IF x > 0.0 THEN
440
            a := y * sqrt(1.0 + sqrr(x / y))
441
        ELSE
442
            a := y
443
        END
444
    END
445
 
446
    RETURN a
447
END hypot;
448
 
449
 
7983 leency 450
END Math.