Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
7597 akron1 1
(*
2
    Copyright 2013, 2014, 2018 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;
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
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;
254
VAR
255
    res: REAL;
256
 
6613 leency 257
BEGIN
7597 akron1 258
    IF IsZero(x) THEN
259
        res := 0.0
260
    ELSE
261
        res := (exp(x) - exp(-x)) / 2.0
262
    END
263
    RETURN res
6613 leency 264
END sinh;
265
 
7597 akron1 266
 
267
PROCEDURE cosh* (x: REAL): REAL;
268
VAR
269
    res: REAL;
270
 
6613 leency 271
BEGIN
7597 akron1 272
    IF IsZero(x) THEN
273
        res := 1.0
274
    ELSE
275
        res := (exp(x) + exp(-x)) / 2.0
276
    END
277
    RETURN res
6613 leency 278
END cosh;
279
 
7597 akron1 280
 
281
PROCEDURE tanh* (x: REAL): REAL;
282
VAR
283
    res: REAL;
284
 
6613 leency 285
BEGIN
7597 akron1 286
    IF IsZero(x) THEN
287
        res := 0.0
288
    ELSE
289
        res := sinh(x) / cosh(x)
290
    END
291
    RETURN res
6613 leency 292
END tanh;
293
 
7597 akron1 294
 
295
PROCEDURE arcsinh* (x: REAL): REAL;
296
    RETURN ln(x + sqrt((x * x) + 1.0))
6613 leency 297
END arcsinh;
298
 
7597 akron1 299
 
300
PROCEDURE arccosh* (x: REAL): REAL;
301
    RETURN ln(x + sqrt((x - 1.0) / (x + 1.0)) * (x + 1.0))
6613 leency 302
END arccosh;
303
 
7597 akron1 304
 
305
PROCEDURE arctanh* (x: REAL): REAL;
306
VAR
307
    res: REAL;
308
 
6613 leency 309
BEGIN
7597 akron1 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
6613 leency 318
END arctanh;
319
 
7597 akron1 320
 
321
PROCEDURE floor* (x: REAL): REAL;
322
VAR
323
    f: REAL;
324
 
6613 leency 325
BEGIN
7597 akron1 326
    f := frac(x);
327
    x := x - f;
328
    IF f < 0.0 THEN
329
        x := x - 1.0
330
    END
331
    RETURN x
6613 leency 332
END floor;
333
 
7597 akron1 334
 
335
PROCEDURE ceil* (x: REAL): REAL;
336
VAR
337
    f: REAL;
338
 
6613 leency 339
BEGIN
7597 akron1 340
    f := frac(x);
341
    x := x - f;
342
    IF f > 0.0 THEN
343
        x := x + 1.0
344
    END
345
    RETURN x
6613 leency 346
END ceil;
347
 
7597 akron1 348
 
349
PROCEDURE power* (base, exponent: REAL): REAL;
350
VAR
351
    res: REAL;
352
 
6613 leency 353
BEGIN
7597 akron1 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
6613 leency 362
END power;
363
 
7597 akron1 364
 
365
PROCEDURE sgn* (x: REAL): INTEGER;
366
VAR
367
    res: INTEGER;
368
 
6613 leency 369
BEGIN
7597 akron1 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
6613 leency 378
END sgn;
7597 akron1 379
 
6613 leency 380
 
381
END Math.