Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
7983 leency 1
(*
2
    Copyright 2013, 2014, 2018, 2019 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 .
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
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 := exp(2.0 * x);
275
        x := (x - 1.0) / (x + 1.0)
276
    END
277
 
278
    RETURN x
279
END tanh;
280
 
281
 
282
PROCEDURE arsinh* (x: REAL): REAL;
283
    RETURN ln(x + sqrt(x * x + 1.0))
284
END arsinh;
285
 
286
 
287
PROCEDURE arcosh* (x: REAL): REAL;
288
    RETURN ln(x + sqrt(x * x - 1.0))
289
END arcosh;
290
 
291
 
292
PROCEDURE artanh* (x: REAL): REAL;
293
VAR
294
    res: REAL;
295
 
296
BEGIN
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
305
END artanh;
306
 
307
 
308
PROCEDURE floor* (x: REAL): REAL;
309
VAR
310
    f: REAL;
311
 
312
BEGIN
313
    f := frac(x);
314
    x := x - f;
315
    IF f < 0.0 THEN
316
        x := x - 1.0
317
    END
318
    RETURN x
319
END floor;
320
 
321
 
322
PROCEDURE ceil* (x: REAL): REAL;
323
VAR
324
    f: REAL;
325
 
326
BEGIN
327
    f := frac(x);
328
    x := x - f;
329
    IF f > 0.0 THEN
330
        x := x + 1.0
331
    END
332
    RETURN x
333
END ceil;
334
 
335
 
336
PROCEDURE power* (base, exponent: REAL): REAL;
337
VAR
338
    res: REAL;
339
 
340
BEGIN
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
349
END power;
350
 
351
 
352
PROCEDURE sgn* (x: REAL): INTEGER;
353
VAR
354
    res: INTEGER;
355
 
356
BEGIN
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
364
 
365
    RETURN res
366
END sgn;
367
 
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
 
384
END Math.