Subversion Repositories Kolibri OS

Rev

Rev 6613 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 6613 Rev 7597
Line 1... Line 1...
1
(*
1
(*
2
    Copyright 2016 Anton Krotov
2
    Copyright 2013, 2014, 2018 Anton Krotov
Line 3... Line 3...
3
 
3
 
4
    This program is free software: you can redistribute it and/or modify
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
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
6
    the Free Software Foundation, either version 3 of the License, or
Line 15... Line 15...
15
    along with this program.  If not, see .
15
    along with this program.  If not, see .
16
*)
16
*)
Line 17... Line 17...
17
 
17
 
Line 18... Line 18...
18
MODULE Math;
18
MODULE Math;
Line 19... Line -...
19
 
-
 
20
IMPORT sys := SYSTEM;
-
 
Line -... Line 19...
-
 
19
 
-
 
20
IMPORT SYSTEM;
-
 
21
 
-
 
22
 
-
 
23
CONST
-
 
24
 
21
 
25
    pi* = 3.141592653589793;
-
 
26
    e*  = 2.718281828459045;
-
 
27
 
Line 22... Line -...
22
CONST pi* = 3.141592653589793D+00;
-
 
23
      e*  = 2.718281828459045D+00;
-
 
24
 
28
 
25
VAR Inf*, nInf*: LONGREAL;
29
PROCEDURE IsNan* (x: REAL): BOOLEAN;
26
 
30
VAR
27
PROCEDURE IsNan*(x: LONGREAL): BOOLEAN;
31
    h, l: SET;
28
VAR h, l: SET;
32
 
Line -... Line 33...
-
 
33
BEGIN
29
BEGIN
34
    SYSTEM.GET(SYSTEM.ADR(x), l);
30
  sys.GET(sys.ADR(x), l);
35
    SYSTEM.GET(SYSTEM.ADR(x) + 4, h)
31
  sys.GET(sys.ADR(x) + 4, h);
36
    RETURN (h * {20..30} = {20..30}) & ((h * {0..19} # {}) OR (l * {0..31} # {}))
Line -... Line 37...
-
 
37
END IsNan;
32
  RETURN (h * {20..30} = {20..30}) & ((h * {0..19} # {}) OR (l * {0..31} # {}))
38
 
-
 
39
 
33
END IsNan;
40
PROCEDURE IsInf* (x: REAL): BOOLEAN;
-
 
41
    RETURN ABS(x) = SYSTEM.INF()
34
 
42
END IsInf;
35
PROCEDURE IsInf*(x: LONGREAL): BOOLEAN;
43
 
36
  RETURN ABS(x) = sys.INF(LONGREAL)
44
 
37
END IsInf;
45
PROCEDURE Max (a, b: REAL): REAL;
38
 
46
VAR
39
PROCEDURE Max(A, B: LONGREAL): LONGREAL;
47
    res: REAL;
40
VAR Res: LONGREAL;
48
 
41
BEGIN
49
BEGIN
Line -... Line 50...
-
 
50
    IF a > b THEN
42
  IF A > B THEN
51
        res := a
-
 
52
    ELSE
43
    Res := A
53
        res := b
-
 
54
    END
44
  ELSE
55
    RETURN res
45
    Res := B
56
END Max;
46
  END
57
 
47
  RETURN Res
58
 
48
END Max;
59
PROCEDURE Min (a, b: REAL): REAL;
49
 
60
VAR
50
PROCEDURE Min(A, B: LONGREAL): LONGREAL;
61
    res: REAL;
51
VAR Res: LONGREAL;
62
 
Line -... Line 63...
-
 
63
BEGIN
52
BEGIN
64
    IF a < b THEN
-
 
65
        res := a
-
 
66
    ELSE
53
  IF A < B THEN
67
        res := b
-
 
68
    END
54
    Res := A
69
    RETURN res
55
  ELSE
70
END Min;
56
    Res := B
71
 
57
  END
72
 
58
  RETURN Res
73
PROCEDURE SameValue (a, b: REAL): BOOLEAN;
59
END Min;
74
VAR
60
 
75
    eps: REAL;
61
PROCEDURE SameValue(A, B: LONGREAL): BOOLEAN;
76
    res: BOOLEAN;
62
VAR Epsilon: LONGREAL; Res: BOOLEAN;
77
 
Line -... Line 78...
-
 
78
BEGIN
63
BEGIN
79
    eps := Max(Min(ABS(a), ABS(b)) * 1.0E-12, 1.0E-12);
64
  Epsilon := Max(Min(ABS(A), ABS(B)) * 1.0D-12, 1.0D-12);
80
    IF a > b THEN
65
  IF A > B THEN
81
        res := (a - b) <= eps
Line -... Line 82...
-
 
82
    ELSE
66
    Res := (A - B) <= Epsilon
83
        res := (b - a) <= eps
67
  ELSE
84
    END
68
    Res := (B - A) <= Epsilon
85
    RETURN res
-
 
86
END SameValue;
-
 
87
 
-
 
88
 
-
 
89
PROCEDURE IsZero (x: REAL): BOOLEAN;
-
 
90
    RETURN ABS(x) <= 1.0E-12
69
  END
91
END IsZero;
70
  RETURN Res
92
 
Line -... Line 93...
-
 
93
 
71
END SameValue;
94
PROCEDURE [stdcall] sqrt* (x: REAL): REAL;
72
 
95
BEGIN
73
PROCEDURE IsZero(x: LONGREAL): BOOLEAN;
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
    )
74
  RETURN ABS(x) <= 1.0D-12
102
    RETURN 0.0
75
END IsZero;
103
END sqrt;
Line -... Line 104...
-
 
104
 
76
 
105
 
77
PROCEDURE [stdcall] sqrt*(x: LONGREAL): LONGREAL;
106
PROCEDURE [stdcall] sin* (x: REAL): REAL;
78
BEGIN
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                *)
79
  sys.CODE("DD4508D9FAC9C20800")
113
    )
80
  RETURN 0.0D0
114
    RETURN 0.0
Line -... Line 115...
-
 
115
END sin;
81
END sqrt;
116
 
82
 
117
 
83
PROCEDURE [stdcall] sin*(x: LONGREAL): LONGREAL;
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                *)
84
BEGIN
125
    )
85
  sys.CODE("DD4508D9FEC9C20800")
126
    RETURN 0.0
Line -... Line 127...
-
 
127
END cos;
86
  RETURN 0.0D0
128
 
87
END sin;
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                    *)
88
 
135
    0DEH, 0F9H,                    (*  fdivp st1, st              *)
-
 
136
    0C9H,                          (*  leave                      *)
89
PROCEDURE [stdcall] cos*(x: LONGREAL): LONGREAL;
137
    0C2H, 008H, 000H               (*  ret     08h                *)
90
BEGIN
138
    )
Line -... Line 139...
-
 
139
    RETURN 0.0
91
  sys.CODE("DD4508D9FFC9C20800")
140
END tan;
92
  RETURN 0.0D0
141
 
93
END cos;
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                     *)
94
 
149
    0C9H,                          (*  leave                      *)
95
PROCEDURE [stdcall] tan*(x: LONGREAL): LONGREAL;
150
    0C2H, 010H, 000H               (*  ret     10h                *)
Line -... Line 151...
-
 
151
    )
96
BEGIN
152
    RETURN 0.0
97
  sys.CODE("DD4508D9F2DEC9C9C20800")
153
END arctan2;
-
 
154
 
-
 
155
 
-
 
156
PROCEDURE [stdcall] ln* (x: REAL): REAL;
-
 
157
BEGIN
-
 
158
    SYSTEM.CODE(
98
  RETURN 0.0D0
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
    )
99
END tan;
165
    RETURN 0.0
100
 
166
END ln;
Line -... Line 167...
-
 
167
 
101
PROCEDURE [stdcall] arctan2*(y, x: LONGREAL): LONGREAL;
168
 
102
BEGIN
169
PROCEDURE [stdcall] log* (base, x: REAL): REAL;
-
 
170
BEGIN             
103
  sys.CODE("DD4508DD4510D9F3C9C21000")
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                *)
104
  RETURN 0.0D0
181
    )
105
END arctan2;
182
    RETURN 0.0
Line -... Line 183...
-
 
183
END log;
106
 
184
 
107
PROCEDURE [stdcall] ln*(x: LONGREAL): LONGREAL;
185
 
-
 
186
PROCEDURE [stdcall] exp* (x: REAL): REAL;
108
BEGIN
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,
109
  sys.CODE("D9EDDD4508D9F1C9C20800")
196
    0C9H,                       (*  leave                      *)
110
  RETURN 0.0D0
197
    0C2H, 008H, 000H            (*  ret     08h                *)
Line -... Line 198...
-
 
198
    )
111
END ln;
199
    RETURN 0.0
112
 
200
END exp;
-
 
201
 
-
 
202
 
113
PROCEDURE [stdcall] log*(base, x: LONGREAL): LONGREAL;
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               *)
114
BEGIN
214
    )
115
  sys.CODE("D9E8DD4510D9F1D9E8DD4508D9F1DEF9C9C21000")
215
    RETURN 0.0
Line -... Line 216...
-
 
216
END round;
116
  RETURN 0.0D0
217
 
117
END log;
218
 
118
 
219
PROCEDURE [stdcall] frac* (x: REAL): REAL;
Line -... Line 220...
-
 
220
BEGIN
119
PROCEDURE [stdcall] exp*(x: LONGREAL): LONGREAL;
221
    SYSTEM.CODE(
120
BEGIN
222
    050H,
121
  sys.CODE("DD4508D9EADEC9D9C0D9FCDCE9D9C9D9F0D9E8DEC1D9FDDDD9C9C20800")
223
    0DDH, 045H, 008H,           (*  fld     qword [ebp + 08h]  *)
Line -... Line 224...
-
 
224
    0D9H, 0C0H, 0D9H, 03CH,
122
  RETURN 0.0D0
225
    024H, 0D9H, 07CH, 024H,
123
END exp;
226
    002H, 066H, 081H, 04CH,
124
 
227
    024H, 002H, 000H, 00FH,
Line -... Line 228...
-
 
228
    0D9H, 06CH, 024H, 002H,
125
PROCEDURE [stdcall] round*(x: LONGREAL): LONGREAL;
229
    0D9H, 0FCH, 0D9H, 02CH,
-
 
230
    024H, 0DEH, 0E9H,
126
BEGIN
231
    0C9H,                       (*  leave                     *)
-
 
232
    0C2H, 008H, 000H            (*  ret     08h               *)
127
  sys.CODE("DD4508D97DF4D97DF666814DF60003D96DF6D9FCD96DF4C9C20800")
233
    )
128
  RETURN 0.0D0
234
    RETURN 0.0
129
END round;
235
END frac;
130
 
236
 
131
PROCEDURE [stdcall] frac*(x: LONGREAL): LONGREAL;
237
 
132
BEGIN
238
PROCEDURE arcsin* (x: REAL): REAL;
133
  sys.CODE("50DD4508D9C0D93C24D97C240266814C2402000FD96C2402D9FCD92C24DEE9C9C20800")
239
    RETURN arctan2(x, sqrt(1.0 - x * x))
134
  RETURN 0.0D0
240
END arcsin;
Line -... Line 241...
-
 
241
 
135
END frac;
242
 
-
 
243
PROCEDURE arccos* (x: REAL): REAL;
136
 
244
    RETURN arctan2(sqrt(1.0 - x * x), x)
-
 
245
END arccos;
137
PROCEDURE arcsin*(x: LONGREAL): LONGREAL;
246
 
138
  RETURN arctan2(x, sqrt(1.0D0 - x * x))
247
 
139
END arcsin;
248
PROCEDURE arctan* (x: REAL): REAL;
140
 
249
    RETURN arctan2(x, 1.0)
141
PROCEDURE arccos*(x: LONGREAL): LONGREAL;
250
END arctan;
142
  RETURN arctan2(sqrt(1.0D0 - x * x), x)
251
 
143
END arccos;
252
 
144
 
253
PROCEDURE sinh* (x: REAL): REAL;
Line -... Line 254...
-
 
254
VAR
145
PROCEDURE arctan*(x: LONGREAL): LONGREAL;
255
    res: REAL;
-
 
256
 
146
  RETURN arctan2(x, 1.0D0)
257
BEGIN
-
 
258
    IF IsZero(x) THEN
147
END arctan;
259
        res := 0.0
148
 
260
    ELSE
149
PROCEDURE sinh*(x: LONGREAL): LONGREAL;
261
        res := (exp(x) - exp(-x)) / 2.0
150
VAR Res: LONGREAL;
262
    END
151
BEGIN
263
    RETURN res
152
  IF IsZero(x) THEN
264
END sinh;
153
    Res := 0.0D0
265
 
154
  ELSE
266
 
Line -... Line 267...
-
 
267
PROCEDURE cosh* (x: REAL): REAL;
155
    Res := (exp(x) - exp(-x)) / 2.0D0
268
VAR
156
  END
269
    res: REAL;
157
  RETURN Res
270
 
Line -... Line 271...
-
 
271
BEGIN
158
END sinh;
272
    IF IsZero(x) THEN
159
 
273
        res := 1.0
160
PROCEDURE cosh*(x: LONGREAL): LONGREAL;
274
    ELSE
Line -... Line 275...
-
 
275
        res := (exp(x) + exp(-x)) / 2.0
161
VAR Res: LONGREAL;
276
    END
-
 
277
    RETURN res
162
BEGIN
278
END cosh;
-
 
279
 
163
  IF IsZero(x) THEN
280
 
164
    Res := 1.0D0
281
PROCEDURE tanh* (x: REAL): REAL;
165
  ELSE
282
VAR
166
    Res := (exp(x) + exp(-x)) / 2.0D0
283
    res: REAL;
167
  END
284
 
168
  RETURN Res
285
BEGIN
169
END cosh;
286
    IF IsZero(x) THEN
170
 
287
        res := 0.0
171
PROCEDURE tanh*(x: LONGREAL): LONGREAL;
288
    ELSE
172
VAR Res: LONGREAL;
289
        res := sinh(x) / cosh(x)
Line -... Line 290...
-
 
290
    END
173
BEGIN
291
    RETURN res
-
 
292
END tanh;
174
  IF IsZero(x) THEN
293
 
-
 
294
 
175
    Res := 0.0D0
295
PROCEDURE arcsinh* (x: REAL): REAL;
176
  ELSE
296
    RETURN ln(x + sqrt((x * x) + 1.0))
177
    Res := sinh(x) / cosh(x)
297
END arcsinh;
178
  END
298
 
179
  RETURN Res
299
 
180
END tanh;
300
PROCEDURE arccosh* (x: REAL): REAL;
181
 
301
    RETURN ln(x + sqrt((x - 1.0) / (x + 1.0)) * (x + 1.0))
182
PROCEDURE arcsinh*(x: LONGREAL): LONGREAL;
302
END arccosh;
Line -... Line 303...
-
 
303
 
183
  RETURN ln(x + sqrt((x * x) + 1.0D0))
304
 
-
 
305
PROCEDURE arctanh* (x: REAL): REAL;
184
END arcsinh;
306
VAR
-
 
307
    res: REAL;
185
 
308
 
186
PROCEDURE arccosh*(x: LONGREAL): LONGREAL;
309
BEGIN
187
  RETURN ln(x + sqrt((x - 1.0D0) / (x + 1.0D0)) * (x + 1.0D0))
310
    IF SameValue(x, 1.0) THEN
188
END arccosh;
311
        res := SYSTEM.INF()
189
 
312
    ELSIF SameValue(x, -1.0) THEN
190
PROCEDURE arctanh*(x: LONGREAL): LONGREAL;
313
        res := -SYSTEM.INF()
191
VAR Res: LONGREAL;
314
    ELSE
192
BEGIN
315
        res := 0.5 * ln((1.0 + x) / (1.0 - x))
Line -... Line 316...
-
 
316
    END
193
  IF SameValue(x, 1.0D0) THEN
317
    RETURN res
-
 
318
END arctanh;
194
    Res := Inf
319
 
-
 
320
 
195
  ELSIF SameValue(x, -1.0D0) THEN
321
PROCEDURE floor* (x: REAL): REAL;
196
    Res := nInf
322
VAR
197
  ELSE
323
    f: REAL;
198
    Res := 0.5D0 * ln((1.0D0 + x) / (1.0D0 - x))
324
 
199
  END
325
BEGIN
200
  RETURN Res
326
    f := frac(x);
201
END arctanh;
327
    x := x - f;
202
 
328
    IF f < 0.0 THEN
203
PROCEDURE floor*(x: LONGREAL): LONGREAL;
329
        x := x - 1.0
204
VAR f: LONGREAL;
330
    END
Line -... Line 331...
-
 
331
    RETURN x
205
BEGIN
332
END floor;
-
 
333
 
206
  f := frac(x);
334
 
-
 
335
PROCEDURE ceil* (x: REAL): REAL;
207
  x := x - f;
336
VAR
208
  IF f < 0.0D0 THEN
337
    f: REAL;
209
    x := x - 1.0D0
338
 
210
  END
339
BEGIN
211
  RETURN x
340
    f := frac(x);
212
END floor;
341
    x := x - f;
213
 
342
    IF f > 0.0 THEN
214
PROCEDURE ceil*(x: LONGREAL): LONGREAL;
343
        x := x + 1.0
215
VAR f: LONGREAL;
344
    END
216
BEGIN
345
    RETURN x
Line 217... Line 346...
217
  f := frac(x);
346
END ceil;
218
  x := x - f;
-
 
219
  IF f > 0.0D0 THEN
-
 
220
    x := x + 1.0D0
347
 
221
  END
348