@live-codes/pascal-wasm 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +501 -0
- package/README.md +278 -0
- package/THIRD-PARTY-NOTICES.md +48 -0
- package/assets/pas2js.wasm +0 -0
- package/assets/rtl/Rtl.BrowserLoadHelper.pas +179 -0
- package/assets/rtl/browserconsole.pas +190 -0
- package/assets/rtl/classes.pas +11371 -0
- package/assets/rtl/js.pas +2211 -0
- package/assets/rtl/manifest.json +19 -0
- package/assets/rtl/math.pas +903 -0
- package/assets/rtl/p2jsres.pp +334 -0
- package/assets/rtl/rtl.js +1563 -0
- package/assets/rtl/rtlconsts.pas +97 -0
- package/assets/rtl/simplelinkedlist.pas +152 -0
- package/assets/rtl/system.pas +1166 -0
- package/assets/rtl/sysutils.pas +8959 -0
- package/assets/rtl/types.pas +2296 -0
- package/assets/rtl/typinfo.pas +1680 -0
- package/assets/rtl/web.pas +3586 -0
- package/assets/rtl/weborworker.pas +2101 -0
- package/dist/pascal-wasm.iife.min.js +6 -0
- package/dist/pascal-wasm.iife.min.js.map +7 -0
- package/package.json +54 -0
- package/src/assets.js +119 -0
- package/src/compiler.js +142 -0
- package/src/config.js +24 -0
- package/src/iife.js +27 -0
- package/src/index.js +130 -0
- package/src/vendor/browser_wasi_shim/debug.js +1 -0
- package/src/vendor/browser_wasi_shim/fd.js +1 -0
- package/src/vendor/browser_wasi_shim/fs_mem.js +1 -0
- package/src/vendor/browser_wasi_shim/fs_opfs.js +1 -0
- package/src/vendor/browser_wasi_shim/index.js +1 -0
- package/src/vendor/browser_wasi_shim/strace.js +1 -0
- package/src/vendor/browser_wasi_shim/wasi.js +1 -0
- package/src/vendor/browser_wasi_shim/wasi_defs.js +1 -0
- package/types/index.d.ts +89 -0
|
@@ -0,0 +1,903 @@
|
|
|
1
|
+
{
|
|
2
|
+
This file is part of the Pas2JS run time library.
|
|
3
|
+
Copyright (c) 2017 by Mattias Gaertner
|
|
4
|
+
|
|
5
|
+
See the file COPYING.FPC, included in this distribution,
|
|
6
|
+
for details about the copyright.
|
|
7
|
+
|
|
8
|
+
This program is distributed in the hope that it will be useful,
|
|
9
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
10
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
11
|
+
|
|
12
|
+
**********************************************************************}
|
|
13
|
+
{$IFNDEF FPC_DOTTEDUNITS}
|
|
14
|
+
unit Math;
|
|
15
|
+
{$ENDIF}
|
|
16
|
+
|
|
17
|
+
{$mode objfpc}
|
|
18
|
+
|
|
19
|
+
interface
|
|
20
|
+
|
|
21
|
+
const
|
|
22
|
+
MinInteger = -$fffffffffffff+1;
|
|
23
|
+
MaxInteger = $fffffffffffff;
|
|
24
|
+
MinDouble = 5.0e-324;
|
|
25
|
+
MaxDouble = 1.7e+308;
|
|
26
|
+
Epsilon = 1.1e-10;
|
|
27
|
+
const
|
|
28
|
+
NaN: Double; external name 'NaN';
|
|
29
|
+
Infinity: Double; external name 'Infinity';
|
|
30
|
+
NegInfinity: Double; external name '-Infinity';
|
|
31
|
+
|
|
32
|
+
type
|
|
33
|
+
float = double;
|
|
34
|
+
|
|
35
|
+
//EInvalidArgument = class(EMathError);
|
|
36
|
+
|
|
37
|
+
function Min(const a, b: Double): Double; varargs; external name 'Math.min'; overload;
|
|
38
|
+
function Max(const a, b: Double): Double; varargs; external name 'Math.max'; overload;
|
|
39
|
+
function Min(const a, b: NativeLargeUInt): NativeLargeUInt; varargs; external name 'Math.min'; overload;
|
|
40
|
+
function Max(const a, b: NativeLargeUInt): NativeLargeUInt; varargs; external name 'Math.max'; overload;
|
|
41
|
+
function Min(const a, b: NativeLargeInt): NativeLargeInt; varargs; external name 'Math.min'; overload;
|
|
42
|
+
function Max(const a, b: NativeLargeInt): NativeLargeInt; varargs; external name 'Math.max'; overload;
|
|
43
|
+
function Min(const a, b: Integer): Integer; varargs; external name 'Math.min'; overload;
|
|
44
|
+
function Max(const a, b: Integer): Integer; varargs; external name 'Math.max'; overload;
|
|
45
|
+
|
|
46
|
+
function InRange(const AValue, AMin, AMax: Integer): Boolean; assembler; overload;
|
|
47
|
+
function InRange(const AValue, AMin, AMax: Double): Boolean; assembler; overload;
|
|
48
|
+
|
|
49
|
+
function EnsureRange(const AValue, AMin, AMax: Integer): Integer; assembler; overload;
|
|
50
|
+
function EnsureRange(const AValue, AMin, AMax: Double): Double; assembler; overload;
|
|
51
|
+
|
|
52
|
+
type
|
|
53
|
+
TRoundToRange = -37..37;
|
|
54
|
+
|
|
55
|
+
function RoundTo(const AValue: Double; const Digits: TRoundToRange): Double;
|
|
56
|
+
function SimpleRoundTo(const AValue: Double; const Digits: TRoundToRange = -2): Double;
|
|
57
|
+
|
|
58
|
+
function randg(mean,stddev : float) : float;
|
|
59
|
+
function RandomRange(const aFrom, aTo: Integer): Integer;
|
|
60
|
+
function RandomRange(const aFrom, aTo: NativeLargeInt): NativeLargeInt;
|
|
61
|
+
|
|
62
|
+
Type
|
|
63
|
+
TValueSign = -1..1;
|
|
64
|
+
|
|
65
|
+
const
|
|
66
|
+
NegativeValue = -1;
|
|
67
|
+
ZeroValue = 0;
|
|
68
|
+
PositiveValue = 1;
|
|
69
|
+
|
|
70
|
+
function Sign(const AValue: NativeInt): TValueSign; external name 'Math.sign'; overload;
|
|
71
|
+
function Sign(const AValue: Double): TValueSign; external name 'Math.sign'; overload;
|
|
72
|
+
|
|
73
|
+
function IsZero(const d: Double; Epsilon: Double): Boolean; overload;
|
|
74
|
+
function IsZero(const d: Double): Boolean; overload;
|
|
75
|
+
|
|
76
|
+
function IsNaN(const v: JSValue): boolean; external name {$IFDEF ECMAScript5}'isNaN'{$ELSE}'Number.isNaN'{$ENDIF}; overload;
|
|
77
|
+
function IsFinite(const d: JSValue): Boolean; external name 'isFinite'; overload;// false if NaN, positive or negative infinity
|
|
78
|
+
function IsInfinite(const d: JSValue): Boolean; assembler; overload; // negative or positive infinity
|
|
79
|
+
{$IFDEF ECMAScript6}
|
|
80
|
+
function IsInteger(const d: JSValue): Boolean; external name 'Number.isInteger'; // any integer representable by a double
|
|
81
|
+
function IsSafeInteger(const d: JSValue): Boolean; external name 'Number.isSafeInteger'; // an integer between MinInteger and MaxInteger, inclusive
|
|
82
|
+
{$ENDIF}
|
|
83
|
+
|
|
84
|
+
function SameValue(const A, B: Double; Epsilon: Double = 0.0): Boolean; overload;
|
|
85
|
+
|
|
86
|
+
// function Abs is in System.pas
|
|
87
|
+
function ArcCos(const A : Double): Double; external name 'Math.acos';
|
|
88
|
+
function ArcCosH(const A: Double): Double; external name 'Math.acosh'; // not on IE
|
|
89
|
+
function ArcSin(const A : Double): Double; external name 'Math.asin';
|
|
90
|
+
function ArcSinH(const A : Double): Double; external name 'Math.asinh'; // not on IE
|
|
91
|
+
function ArcTanH(const A: Double): Double; external name 'Math.atanh'; // not on IE
|
|
92
|
+
function CosH(const A: Double): Double; external name 'Math.cosh'; // not on IE
|
|
93
|
+
procedure SinCos(const A: Double; var B: Double; var C: Double);
|
|
94
|
+
function ExpM1(const A: Double): Double; external name 'Math.expm1'; // not on IE
|
|
95
|
+
function FRound(const A: Double): Double; overload; external name 'Math.fround'; // not on IE
|
|
96
|
+
function FTrunc(const A: Double): double; overload; external name 'Math.trunc'; // not on IE
|
|
97
|
+
function Hypot(const A : Double): Double; varargs; external name 'Math.hypot'; // not on IE
|
|
98
|
+
function IMul(const A, B: Integer): Integer; external name 'Math.imul'; // not on IE
|
|
99
|
+
function Log10(const A: Double): Double; external name 'Math.log10';
|
|
100
|
+
function Log1p(const A: Double): Double; external name 'Math.log1p'; // not on IE
|
|
101
|
+
function Log2(const A: Double): Double; external name 'Math.log2'; // not on IE
|
|
102
|
+
function LogN(const Base, N: Double): Double;
|
|
103
|
+
function Power(const Base, Exponent: Double): Double; external name 'Math.pow';
|
|
104
|
+
// ln, round, sqrt, trunc, cos, sin, arctan, round, exp are in unit system
|
|
105
|
+
function Ceil(const A: Double): Integer;
|
|
106
|
+
function Floor(const A: Double): Integer;
|
|
107
|
+
function Ceil64(const A: Double): NativeLargeInt;
|
|
108
|
+
function Floor64(const A: Double): NativeLargeInt;
|
|
109
|
+
function ldexp(x : double;const p : Integer) : double;
|
|
110
|
+
procedure Frexp(X: double; out Mantissa: double; out Exponent: integer);
|
|
111
|
+
function lnxp1(x : double) : double;
|
|
112
|
+
|
|
113
|
+
function IntPower(base : float;const exponent : Integer) : double;
|
|
114
|
+
|
|
115
|
+
procedure DivMod(Dividend: LongInt; Divisor: Word; out Result, Remainder: Word);
|
|
116
|
+
procedure DivMod(Dividend: LongInt; Divisor: Word; out Result, Remainder: SmallInt);
|
|
117
|
+
procedure DivMod(Dividend: DWord; Divisor: DWord; out Result, Remainder: DWord);
|
|
118
|
+
procedure DivMod(Dividend: LongInt; Divisor: LongInt; out Result, Remainder: LongInt);
|
|
119
|
+
|
|
120
|
+
{ Angle conversion }
|
|
121
|
+
function DegToRad(deg : double) : double;
|
|
122
|
+
function RadToDeg(rad : double) : double;
|
|
123
|
+
function GradToRad(grad : double) : double;
|
|
124
|
+
function RadToGrad(rad : double) : double;
|
|
125
|
+
function DegToGrad(deg : double) : double;
|
|
126
|
+
function GradToDeg(grad : double) : double;
|
|
127
|
+
{ one cycle are 2*Pi rad }
|
|
128
|
+
function CycleToRad(cycle : double) : double;
|
|
129
|
+
function RadToCycle(rad : double) : double;
|
|
130
|
+
Function DegNormalize(deg : double) : double;
|
|
131
|
+
|
|
132
|
+
function Norm(const data : array of double) : double;
|
|
133
|
+
|
|
134
|
+
// Statistical functions
|
|
135
|
+
function Mean(const data : array of double) : double;
|
|
136
|
+
function Sum(const data : array of double) : double;
|
|
137
|
+
procedure SumsAndSquares(const data : Array of Double; out Sum,SumOfSquares : double);
|
|
138
|
+
|
|
139
|
+
function StdDev(const data : array of Double) : float;
|
|
140
|
+
procedure MeanAndStdDev(const data : array of Double; out Mean,StdDev : double);
|
|
141
|
+
function Variance(const data : array of Double) : double;
|
|
142
|
+
function TotalVariance(const data : array of Double) : double;
|
|
143
|
+
function PopNStdDev(const data : array of Double) : double;
|
|
144
|
+
function PopNVariance(const data : array of Double) : double;
|
|
145
|
+
procedure MomentSkewKurtosis(const data : array of Double; out m1,m2,m3,m4,skew,kurtosis : double);
|
|
146
|
+
|
|
147
|
+
function MaxIntValue(const AData: array of Integer): Integer;
|
|
148
|
+
|
|
149
|
+
// Financial functions
|
|
150
|
+
|
|
151
|
+
Type
|
|
152
|
+
TPaymentTime = (ptEndOfPeriod,ptStartOfPeriod);
|
|
153
|
+
|
|
154
|
+
function FutureValue(ARate: double; NPeriods: Integer;
|
|
155
|
+
APayment, APresentValue: double; APaymentTime: TPaymentTime): double;
|
|
156
|
+
|
|
157
|
+
function InterestRate(NPeriods: Integer; APayment, APresentValue, AFutureValue: double;
|
|
158
|
+
APaymentTime: TPaymentTime): double;
|
|
159
|
+
|
|
160
|
+
function NumberOfPeriods(ARate, APayment, APresentValue, AFutureValue: double;
|
|
161
|
+
APaymentTime: TPaymentTime): double;
|
|
162
|
+
|
|
163
|
+
function Payment(ARate: double; NPeriods: Integer;
|
|
164
|
+
APresentValue, AFutureValue: double; APaymentTime: TPaymentTime): double;
|
|
165
|
+
|
|
166
|
+
function PresentValue(ARate: double; NPeriods: Integer;
|
|
167
|
+
APayment, AFutureValue: double; APaymentTime: TPaymentTime): double;
|
|
168
|
+
|
|
169
|
+
// Miscellaneous
|
|
170
|
+
|
|
171
|
+
function IfThen(val:boolean;const ifTrue:integer; const ifFalse:integer= 0) :integer; overload;
|
|
172
|
+
function IfThen(val:boolean;const ifTrue:double ; const ifFalse:double =0.0):double; overload;
|
|
173
|
+
|
|
174
|
+
Type
|
|
175
|
+
TValueRelationship = -1..1;
|
|
176
|
+
|
|
177
|
+
const
|
|
178
|
+
EqualsValue = 0;
|
|
179
|
+
LessThanValue = Low(TValueRelationship);
|
|
180
|
+
GreaterThanValue = High(TValueRelationship);
|
|
181
|
+
|
|
182
|
+
function CompareValue ( const A, B : Integer) : TValueRelationship;
|
|
183
|
+
function CompareValue ( const A, B : NativeLargeInt) : TValueRelationship;
|
|
184
|
+
function CompareValue ( const A, B : NativeLargeUInt) : TValueRelationship;
|
|
185
|
+
function CompareValue ( const A, B : Double; delta : Double = 0.0) : TValueRelationship;
|
|
186
|
+
|
|
187
|
+
implementation
|
|
188
|
+
|
|
189
|
+
function InRange(const AValue, AMin, AMax: Integer): Boolean; assembler;
|
|
190
|
+
asm
|
|
191
|
+
return (AValue >= AMin) && (AValue <= AMax);
|
|
192
|
+
end;
|
|
193
|
+
|
|
194
|
+
function InRange(const AValue, AMin, AMax: Double): Boolean; assembler;
|
|
195
|
+
asm
|
|
196
|
+
return (AValue >= AMin) && (AValue <= AMax);
|
|
197
|
+
end;
|
|
198
|
+
|
|
199
|
+
function EnsureRange(const AValue, AMin, AMax: Integer): Integer; assembler;
|
|
200
|
+
asm
|
|
201
|
+
if (AValue<AMin){ return AMin;
|
|
202
|
+
} else if (AValue>AMax){ return AMax;
|
|
203
|
+
} else return AValue;
|
|
204
|
+
end;
|
|
205
|
+
|
|
206
|
+
function EnsureRange(const AValue, AMin, AMax: Double): Double; assembler;
|
|
207
|
+
asm
|
|
208
|
+
if (AValue<AMin){ return AMin;
|
|
209
|
+
} else if (AValue>AMax){ return AMax;
|
|
210
|
+
} else return AValue;
|
|
211
|
+
end;
|
|
212
|
+
|
|
213
|
+
function RoundTo(const AValue: Double; const Digits: TRoundToRange): Double;
|
|
214
|
+
var
|
|
215
|
+
RV : Double;
|
|
216
|
+
|
|
217
|
+
begin
|
|
218
|
+
RV:=IntPower(10,Digits);
|
|
219
|
+
Result:=Round(AValue/RV)*RV;
|
|
220
|
+
end;
|
|
221
|
+
|
|
222
|
+
function SimpleRoundTo(const AValue: Double; const Digits: TRoundToRange): Double;
|
|
223
|
+
var
|
|
224
|
+
RV : Double;
|
|
225
|
+
|
|
226
|
+
begin
|
|
227
|
+
RV := IntPower(10, -Digits);
|
|
228
|
+
if AValue < 0 then
|
|
229
|
+
Result := Int((AValue*RV) - 0.5)/RV
|
|
230
|
+
else
|
|
231
|
+
Result := Int((AValue*RV) + 0.5)/RV;
|
|
232
|
+
end;
|
|
233
|
+
|
|
234
|
+
function randg(mean,stddev : float) : float;
|
|
235
|
+
|
|
236
|
+
Var
|
|
237
|
+
U1,S2 : Float;
|
|
238
|
+
|
|
239
|
+
begin
|
|
240
|
+
repeat
|
|
241
|
+
u1:= 2*random-1;
|
|
242
|
+
S2:=Sqr(U1)+sqr(2*random-1);
|
|
243
|
+
until s2<1;
|
|
244
|
+
Result:=Sqrt(-2*ln(S2)/S2)*u1*stddev+Mean;
|
|
245
|
+
end;
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
function RandomRange(const aFrom, aTo: Integer): Integer;
|
|
249
|
+
begin
|
|
250
|
+
Result:=Random(Abs(aFrom-aTo))+Min(aTo,AFrom);
|
|
251
|
+
end;
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
function RandomRange(const aFrom, aTo: NativeLargeInt): NativeLargeInt;
|
|
255
|
+
|
|
256
|
+
Var
|
|
257
|
+
m : NativeLargeInt;
|
|
258
|
+
begin
|
|
259
|
+
if aFrom<aTo then
|
|
260
|
+
M:=aFrom
|
|
261
|
+
else
|
|
262
|
+
M:=aTo;
|
|
263
|
+
Result:=Random(Abs(aFrom-aTo))+M;
|
|
264
|
+
end;
|
|
265
|
+
|
|
266
|
+
const
|
|
267
|
+
DZeroResolution = 1E-12;
|
|
268
|
+
|
|
269
|
+
function IsZero(const d: Double; Epsilon: Double): Boolean;
|
|
270
|
+
begin
|
|
271
|
+
if Epsilon=0 then
|
|
272
|
+
Epsilon:=DZeroResolution;
|
|
273
|
+
Result:=Abs(d)<=Epsilon;
|
|
274
|
+
end;
|
|
275
|
+
|
|
276
|
+
function IsZero(const d: Double): Boolean;
|
|
277
|
+
begin
|
|
278
|
+
Result:=Abs(d)<=DZeroResolution;
|
|
279
|
+
end;
|
|
280
|
+
|
|
281
|
+
function IsInfinite(const d: JSValue): Boolean; assembler;
|
|
282
|
+
asm
|
|
283
|
+
return (d==Infinity) || (d==-Infinity);
|
|
284
|
+
end;
|
|
285
|
+
|
|
286
|
+
function SameValue(const A, B: Double; Epsilon: Double): Boolean;
|
|
287
|
+
begin
|
|
288
|
+
if (Epsilon=0.0) then
|
|
289
|
+
Epsilon:=Max(Min(Abs(A),Abs(B))*DZeroResolution,DZeroResolution);
|
|
290
|
+
if (A>B) then
|
|
291
|
+
Result:=((A-B)<=Epsilon)
|
|
292
|
+
else
|
|
293
|
+
Result:=((B-A)<=Epsilon);
|
|
294
|
+
end;
|
|
295
|
+
|
|
296
|
+
function JSFloor(const A: Double): Double; external name 'Math.floor';
|
|
297
|
+
function JSCeil(const A: Double): Double; external name 'Math.ceil';
|
|
298
|
+
|
|
299
|
+
function Ceil(const A: Double): Integer;
|
|
300
|
+
|
|
301
|
+
begin
|
|
302
|
+
// TODO: add Range check ?
|
|
303
|
+
Result:=trunc(JSCeil(a));
|
|
304
|
+
end;
|
|
305
|
+
|
|
306
|
+
function Floor(const A: Double): Integer;
|
|
307
|
+
|
|
308
|
+
begin
|
|
309
|
+
// TODO: add Range check ?
|
|
310
|
+
Result:=trunc(JSFloor(a));
|
|
311
|
+
end;
|
|
312
|
+
|
|
313
|
+
function Ceil64(const A: Double): NativeLargeInt;
|
|
314
|
+
|
|
315
|
+
begin
|
|
316
|
+
Result:=trunc(JSCeil(a));
|
|
317
|
+
end;
|
|
318
|
+
|
|
319
|
+
function Floor64(const A: Double): NativeLargeInt;
|
|
320
|
+
|
|
321
|
+
begin
|
|
322
|
+
Result:=trunc(JSCeil(a));
|
|
323
|
+
end;
|
|
324
|
+
|
|
325
|
+
procedure Frexp(X: double; out Mantissa: double; out Exponent: integer);
|
|
326
|
+
|
|
327
|
+
begin
|
|
328
|
+
Exponent:=0;
|
|
329
|
+
if (X<>0) then
|
|
330
|
+
if (abs(X)<0.5) then
|
|
331
|
+
repeat
|
|
332
|
+
X:=X*2;
|
|
333
|
+
Dec(Exponent);
|
|
334
|
+
until (abs(X)>=0.5)
|
|
335
|
+
else
|
|
336
|
+
while (abs(X)>=1) do
|
|
337
|
+
begin
|
|
338
|
+
X:=X/2;
|
|
339
|
+
Inc(Exponent);
|
|
340
|
+
end;
|
|
341
|
+
Mantissa:=X;
|
|
342
|
+
end;
|
|
343
|
+
|
|
344
|
+
procedure SinCos(const A: Double; var B: Double; var C: Double);
|
|
345
|
+
begin
|
|
346
|
+
B:=Sin(A);
|
|
347
|
+
C:=Cos(A);
|
|
348
|
+
end;
|
|
349
|
+
|
|
350
|
+
function LogN(const Base,N: Double): Double;
|
|
351
|
+
|
|
352
|
+
begin
|
|
353
|
+
Result:=Ln(N)/Ln(Base);
|
|
354
|
+
end;
|
|
355
|
+
|
|
356
|
+
function lnxp1(x: double): double;
|
|
357
|
+
|
|
358
|
+
var
|
|
359
|
+
y: float;
|
|
360
|
+
|
|
361
|
+
begin
|
|
362
|
+
if (x>=4.0) then
|
|
363
|
+
result:=ln(1.0+x)
|
|
364
|
+
else
|
|
365
|
+
begin
|
|
366
|
+
y:=1.0+x;
|
|
367
|
+
if (y=1.0) then
|
|
368
|
+
result:=x
|
|
369
|
+
else
|
|
370
|
+
begin
|
|
371
|
+
result:=ln(y); { lnxp1(-1) = ln(0) = -Inf }
|
|
372
|
+
if y>0.0 then
|
|
373
|
+
result:=result+(x-(y-1.0))/y;
|
|
374
|
+
end;
|
|
375
|
+
end;
|
|
376
|
+
end;
|
|
377
|
+
|
|
378
|
+
function ldexp(x : double;const p : Integer) : double;
|
|
379
|
+
|
|
380
|
+
begin
|
|
381
|
+
result:=x*intpower(2.0,p);
|
|
382
|
+
end;
|
|
383
|
+
|
|
384
|
+
|
|
385
|
+
function IntPower(base: float; const exponent: Integer): double;
|
|
386
|
+
|
|
387
|
+
var
|
|
388
|
+
i : longint;
|
|
389
|
+
|
|
390
|
+
begin
|
|
391
|
+
if (base = 0.0) and (exponent = 0) then
|
|
392
|
+
result:=1
|
|
393
|
+
else
|
|
394
|
+
begin
|
|
395
|
+
i:=abs(exponent);
|
|
396
|
+
Result:=1.0;
|
|
397
|
+
while i>0 do
|
|
398
|
+
begin
|
|
399
|
+
while (i and 1)=0 do
|
|
400
|
+
begin
|
|
401
|
+
i:=i shr 1;
|
|
402
|
+
base:=sqr(base);
|
|
403
|
+
end;
|
|
404
|
+
i:=i-1;
|
|
405
|
+
Result:=Result*base;
|
|
406
|
+
end;
|
|
407
|
+
if exponent<0 then
|
|
408
|
+
Result:=1.0/Result;
|
|
409
|
+
end;
|
|
410
|
+
end;
|
|
411
|
+
|
|
412
|
+
procedure DivMod(Dividend: LongInt; Divisor: Word; out Result, Remainder: Word);
|
|
413
|
+
begin
|
|
414
|
+
if Dividend < 0 then
|
|
415
|
+
begin
|
|
416
|
+
Dividend:=-Dividend;
|
|
417
|
+
Result:=-(Dividend Div Divisor);
|
|
418
|
+
Remainder:=-(Dividend+(Result*Divisor));
|
|
419
|
+
end
|
|
420
|
+
else
|
|
421
|
+
begin
|
|
422
|
+
Result:=Dividend Div Divisor;
|
|
423
|
+
Remainder:=Dividend-(Result*Divisor);
|
|
424
|
+
end;
|
|
425
|
+
end;
|
|
426
|
+
|
|
427
|
+
|
|
428
|
+
procedure DivMod(Dividend: LongInt; Divisor: Word; out Result,
|
|
429
|
+
Remainder: SmallInt);
|
|
430
|
+
begin
|
|
431
|
+
if Dividend < 0 then
|
|
432
|
+
begin
|
|
433
|
+
Dividend:=-Dividend;
|
|
434
|
+
Result:=-(Dividend Div Divisor);
|
|
435
|
+
Remainder:=-(Dividend+(Result*Divisor));
|
|
436
|
+
end
|
|
437
|
+
else
|
|
438
|
+
begin
|
|
439
|
+
Result:=Dividend Div Divisor;
|
|
440
|
+
Remainder:=Dividend-(Result*Divisor);
|
|
441
|
+
end;
|
|
442
|
+
end;
|
|
443
|
+
|
|
444
|
+
|
|
445
|
+
procedure DivMod(Dividend: DWord; Divisor: DWord; out Result, Remainder: DWord);
|
|
446
|
+
begin
|
|
447
|
+
Result:=Dividend Div Divisor;
|
|
448
|
+
Remainder:=Dividend-(Result*Divisor);
|
|
449
|
+
end;
|
|
450
|
+
|
|
451
|
+
|
|
452
|
+
procedure DivMod(Dividend: LongInt; Divisor: LongInt; out Result,
|
|
453
|
+
Remainder: LongInt);
|
|
454
|
+
|
|
455
|
+
begin
|
|
456
|
+
if Dividend < 0 then
|
|
457
|
+
begin
|
|
458
|
+
Dividend:=-Dividend;
|
|
459
|
+
Result:=-(Dividend Div Divisor);
|
|
460
|
+
Remainder:=-(Dividend+(Result*Divisor));
|
|
461
|
+
end
|
|
462
|
+
else
|
|
463
|
+
begin
|
|
464
|
+
Result:=Dividend Div Divisor;
|
|
465
|
+
Remainder:=Dividend-(Result*Divisor);
|
|
466
|
+
end;
|
|
467
|
+
end;
|
|
468
|
+
|
|
469
|
+
{ ---------------------------------------------------------------------
|
|
470
|
+
Angle conversion
|
|
471
|
+
---------------------------------------------------------------------}
|
|
472
|
+
function DegToRad(deg: double): double;
|
|
473
|
+
|
|
474
|
+
begin
|
|
475
|
+
Result:=deg*(pi/180.0);
|
|
476
|
+
end;
|
|
477
|
+
|
|
478
|
+
|
|
479
|
+
function RadToDeg(rad: double): double;
|
|
480
|
+
|
|
481
|
+
begin
|
|
482
|
+
Result:=rad*(180.0/pi);
|
|
483
|
+
end;
|
|
484
|
+
|
|
485
|
+
|
|
486
|
+
function GradToRad(grad: double): double;
|
|
487
|
+
|
|
488
|
+
begin
|
|
489
|
+
Result:=grad*(pi/200.0);
|
|
490
|
+
end;
|
|
491
|
+
|
|
492
|
+
|
|
493
|
+
function RadToGrad(rad: double): double;
|
|
494
|
+
|
|
495
|
+
begin
|
|
496
|
+
Result:=rad*(200.0/pi);
|
|
497
|
+
end;
|
|
498
|
+
|
|
499
|
+
|
|
500
|
+
function DegToGrad(deg: double): double;
|
|
501
|
+
|
|
502
|
+
begin
|
|
503
|
+
Result:=deg*(200.0/180.0);
|
|
504
|
+
end;
|
|
505
|
+
|
|
506
|
+
|
|
507
|
+
function GradToDeg(grad: double): double;
|
|
508
|
+
|
|
509
|
+
begin
|
|
510
|
+
Result:=grad*(180.0/200.0);
|
|
511
|
+
end;
|
|
512
|
+
|
|
513
|
+
|
|
514
|
+
function CycleToRad(cycle: double): double;
|
|
515
|
+
|
|
516
|
+
begin
|
|
517
|
+
Result:=(2*pi)*cycle;
|
|
518
|
+
end;
|
|
519
|
+
|
|
520
|
+
|
|
521
|
+
function RadToCycle(rad: double): double;
|
|
522
|
+
|
|
523
|
+
begin
|
|
524
|
+
Result:=rad*(1/(2*pi));
|
|
525
|
+
end;
|
|
526
|
+
|
|
527
|
+
|
|
528
|
+
function DegNormalize(deg: double): double;
|
|
529
|
+
|
|
530
|
+
begin
|
|
531
|
+
Result:=Deg-Int(Deg/360)*360;
|
|
532
|
+
If (Result<0) then Result:=Result+360;
|
|
533
|
+
end;
|
|
534
|
+
|
|
535
|
+
function sumofsquares(const data : array of double) : double;
|
|
536
|
+
var
|
|
537
|
+
i,N : longint;
|
|
538
|
+
|
|
539
|
+
begin
|
|
540
|
+
N:=Length(Data);
|
|
541
|
+
Result:=0.0;
|
|
542
|
+
for i:=0 to N-1 do
|
|
543
|
+
Result:=Result+sqr(data[i]);
|
|
544
|
+
end;
|
|
545
|
+
|
|
546
|
+
function Norm(const data: array of double): double;
|
|
547
|
+
begin
|
|
548
|
+
Result:=sqrt(sumofsquares(data));
|
|
549
|
+
end;
|
|
550
|
+
|
|
551
|
+
{ ---------------------------------------------------------------------
|
|
552
|
+
Statistical functions
|
|
553
|
+
---------------------------------------------------------------------}
|
|
554
|
+
|
|
555
|
+
function Sum(const data: array of double): double;
|
|
556
|
+
|
|
557
|
+
var
|
|
558
|
+
i,N : longint;
|
|
559
|
+
|
|
560
|
+
begin
|
|
561
|
+
N:=Length(Data);
|
|
562
|
+
Result:=0.0;
|
|
563
|
+
for i:=0 to N-1 do
|
|
564
|
+
Result:=Result+data[i];
|
|
565
|
+
end;
|
|
566
|
+
|
|
567
|
+
function Mean(const data: array of double): double;
|
|
568
|
+
|
|
569
|
+
Var
|
|
570
|
+
N : integer;
|
|
571
|
+
|
|
572
|
+
begin
|
|
573
|
+
N:=Length(Data);
|
|
574
|
+
if N=0 then
|
|
575
|
+
Result:=0
|
|
576
|
+
else
|
|
577
|
+
Result:=Sum(Data)/N;
|
|
578
|
+
end;
|
|
579
|
+
procedure SumsAndSquares(const data: array of Double; out Sum,
|
|
580
|
+
SumOfSquares: double);
|
|
581
|
+
|
|
582
|
+
var
|
|
583
|
+
i,n : Integer;
|
|
584
|
+
t,s,ss: double;
|
|
585
|
+
|
|
586
|
+
begin
|
|
587
|
+
n:=length(Data);
|
|
588
|
+
ss:=0.0; // Use local vars, var is very inefficient in js
|
|
589
|
+
s:=0.0;
|
|
590
|
+
for i:=0 to N-1 do
|
|
591
|
+
begin
|
|
592
|
+
t:=data[i];
|
|
593
|
+
ss:=ss+sqr(t);
|
|
594
|
+
s:=s+t;
|
|
595
|
+
end;
|
|
596
|
+
Sum:=s;
|
|
597
|
+
SumOfSquares:=ss;
|
|
598
|
+
end;
|
|
599
|
+
|
|
600
|
+
function StdDev(const data: array of Double): float;
|
|
601
|
+
|
|
602
|
+
begin
|
|
603
|
+
Result:=Sqrt(Variance(Data));
|
|
604
|
+
end;
|
|
605
|
+
|
|
606
|
+
function Variance(const data: array of Double): double;
|
|
607
|
+
|
|
608
|
+
var
|
|
609
|
+
n : integer;
|
|
610
|
+
|
|
611
|
+
begin
|
|
612
|
+
N:=Length(Data);
|
|
613
|
+
If N=1 then
|
|
614
|
+
Result:=0
|
|
615
|
+
else
|
|
616
|
+
Result:=TotalVariance(Data)/(N-1);
|
|
617
|
+
end;
|
|
618
|
+
|
|
619
|
+
function TotalVariance(const data: array of Double): double;
|
|
620
|
+
|
|
621
|
+
var
|
|
622
|
+
S,SS : Float;
|
|
623
|
+
N : integer;
|
|
624
|
+
begin
|
|
625
|
+
N:=Length(Data);
|
|
626
|
+
If Length(Data)=1 then
|
|
627
|
+
Result:=0
|
|
628
|
+
else
|
|
629
|
+
begin
|
|
630
|
+
SumsAndSquares(Data,S,SS);
|
|
631
|
+
Result := SS-Sqr(S)/N;
|
|
632
|
+
end;
|
|
633
|
+
end;
|
|
634
|
+
|
|
635
|
+
procedure MeanAndStdDev(const data: array of Double; out Mean, StdDev: double);
|
|
636
|
+
|
|
637
|
+
Var
|
|
638
|
+
I,N : longint;
|
|
639
|
+
M,S : Double;
|
|
640
|
+
|
|
641
|
+
begin
|
|
642
|
+
N:=Length(Data);
|
|
643
|
+
M:=0;
|
|
644
|
+
S:=0;
|
|
645
|
+
For I:=0 to N-1 do
|
|
646
|
+
begin
|
|
647
|
+
M:=M+Data[i];
|
|
648
|
+
S:=S+Sqr(Data[i]);
|
|
649
|
+
end;
|
|
650
|
+
M:=M/N;
|
|
651
|
+
S:=(S-N*Sqr(M));
|
|
652
|
+
If N>1 then
|
|
653
|
+
S:=Sqrt(S/(N-1))
|
|
654
|
+
else
|
|
655
|
+
S:=0;
|
|
656
|
+
Mean:=M;
|
|
657
|
+
StdDev:=S;
|
|
658
|
+
end;
|
|
659
|
+
|
|
660
|
+
function PopNStdDev(const data : array of Double) : double;
|
|
661
|
+
|
|
662
|
+
begin
|
|
663
|
+
Result:=Sqrt(PopnVariance(Data));
|
|
664
|
+
end;
|
|
665
|
+
|
|
666
|
+
function PopNVariance(const data : array of Double) : double;
|
|
667
|
+
|
|
668
|
+
Var
|
|
669
|
+
N : integer;
|
|
670
|
+
|
|
671
|
+
begin
|
|
672
|
+
N:=Length(Data);
|
|
673
|
+
if N=0 then
|
|
674
|
+
Result:=0
|
|
675
|
+
else
|
|
676
|
+
Result:=TotalVariance(Data)/N;
|
|
677
|
+
end;
|
|
678
|
+
|
|
679
|
+
procedure MomentSkewKurtosis(const data: array of Double; out m1, m2, m3, m4, skew, kurtosis: double);
|
|
680
|
+
|
|
681
|
+
var
|
|
682
|
+
i,N: integer;
|
|
683
|
+
deviation, deviation2: double;
|
|
684
|
+
reciprocalN: float;
|
|
685
|
+
// Use local vars for all calculations, var is very slow
|
|
686
|
+
lm1, lm2, lm3, lm4, lskew, lkurtosis: double;
|
|
687
|
+
|
|
688
|
+
begin
|
|
689
|
+
N:=length(Data);
|
|
690
|
+
lm1 := 0;
|
|
691
|
+
reciprocalN := 1/N;
|
|
692
|
+
for i := 0 to N-1 do
|
|
693
|
+
lm1 := lm1 + data[i];
|
|
694
|
+
lm1 := reciprocalN * lm1;
|
|
695
|
+
|
|
696
|
+
lm2 := 0;
|
|
697
|
+
lm3 := 0;
|
|
698
|
+
lm4 := 0;
|
|
699
|
+
for i := 0 to N-1 do
|
|
700
|
+
begin
|
|
701
|
+
deviation := (data[i]-lm1);
|
|
702
|
+
deviation2 := deviation * deviation;
|
|
703
|
+
lm2 := lm2 + deviation2;
|
|
704
|
+
lm3 := lm3 + deviation2 * deviation;
|
|
705
|
+
lm4 := lm4 + deviation2 * deviation2;
|
|
706
|
+
end;
|
|
707
|
+
lm2 := reciprocalN * lm2;
|
|
708
|
+
lm3 := reciprocalN * lm3;
|
|
709
|
+
lm4 := reciprocalN * lm4;
|
|
710
|
+
|
|
711
|
+
lskew := lm3 / (sqrt(lm2)*lm2);
|
|
712
|
+
lkurtosis := lm4 / (lm2 * lm2);
|
|
713
|
+
|
|
714
|
+
m1:=lm1;
|
|
715
|
+
m2:=lm2;
|
|
716
|
+
m3:=lm3;
|
|
717
|
+
m4:=lm4;
|
|
718
|
+
skew:=lskew;
|
|
719
|
+
kurtosis:=lkurtosis;
|
|
720
|
+
end;
|
|
721
|
+
|
|
722
|
+
{ ---------------------------------------------------------------------
|
|
723
|
+
Financial functions
|
|
724
|
+
---------------------------------------------------------------------}
|
|
725
|
+
|
|
726
|
+
function FutureValue(ARate: double; NPeriods: Integer;
|
|
727
|
+
APayment, APresentValue: double; APaymentTime: TPaymentTime): double;
|
|
728
|
+
var
|
|
729
|
+
q, qn, factor: double;
|
|
730
|
+
begin
|
|
731
|
+
if ARate = 0 then
|
|
732
|
+
Result := -APresentValue - APayment * NPeriods
|
|
733
|
+
else begin
|
|
734
|
+
q := 1.0 + ARate;
|
|
735
|
+
qn := power(q, NPeriods);
|
|
736
|
+
factor := (qn - 1) / (q - 1);
|
|
737
|
+
if APaymentTime = ptStartOfPeriod then
|
|
738
|
+
factor := factor * q;
|
|
739
|
+
Result := -(APresentValue * qn + APayment*factor);
|
|
740
|
+
end;
|
|
741
|
+
end;
|
|
742
|
+
|
|
743
|
+
function InterestRate(NPeriods: Integer; APayment, APresentValue, AFutureValue: double;
|
|
744
|
+
APaymentTime: TPaymentTime): double;
|
|
745
|
+
{ The interest rate cannot be calculated analytically. We solve the equation
|
|
746
|
+
numerically by means of the Newton method:
|
|
747
|
+
- guess value for the interest reate
|
|
748
|
+
- calculate at which interest rate the tangent of the curve fv(rate)
|
|
749
|
+
(straight line!) has the requested future vale.
|
|
750
|
+
- use this rate for the next iteration. }
|
|
751
|
+
const
|
|
752
|
+
DELTA = 0.001;
|
|
753
|
+
EPS = 1E-9; // required precision of interest rate (after typ. 6 iterations)
|
|
754
|
+
MAXIT = 20; // max iteration count to protect agains non-convergence
|
|
755
|
+
var
|
|
756
|
+
r1, r2, dr: double;
|
|
757
|
+
fv1, fv2: double;
|
|
758
|
+
iteration: Integer;
|
|
759
|
+
begin
|
|
760
|
+
iteration := 0;
|
|
761
|
+
r1 := 0.05; // inital guess
|
|
762
|
+
repeat
|
|
763
|
+
r2 := r1 + DELTA;
|
|
764
|
+
fv1 := FutureValue(r1, NPeriods, APayment, APresentValue, APaymentTime);
|
|
765
|
+
fv2 := FutureValue(r2, NPeriods, APayment, APresentValue, APaymentTime);
|
|
766
|
+
dr := (AFutureValue - fv1) / (fv2 - fv1) * delta; // tangent at fv(r)
|
|
767
|
+
r1 := r1 + dr; // next guess
|
|
768
|
+
inc(iteration);
|
|
769
|
+
until (abs(dr) < EPS) or (iteration >= MAXIT);
|
|
770
|
+
Result := r1;
|
|
771
|
+
end;
|
|
772
|
+
|
|
773
|
+
function NumberOfPeriods(ARate, APayment, APresentValue, AFutureValue: double;
|
|
774
|
+
APaymentTime: TPaymentTime): double;
|
|
775
|
+
{ Solve the cash flow equation (1) for q^n and take the logarithm }
|
|
776
|
+
var
|
|
777
|
+
q, x1, x2: double;
|
|
778
|
+
begin
|
|
779
|
+
if ARate = 0 then
|
|
780
|
+
Result := -(APresentValue + AFutureValue) / APayment
|
|
781
|
+
else begin
|
|
782
|
+
q := 1.0 + ARate;
|
|
783
|
+
if APaymentTime = ptStartOfPeriod then
|
|
784
|
+
APayment := APayment * q;
|
|
785
|
+
x1 := APayment - AFutureValue * ARate;
|
|
786
|
+
x2 := APayment + APresentValue * ARate;
|
|
787
|
+
if (x2 = 0) // we have to divide by x2
|
|
788
|
+
or (sign(x1) * sign(x2) < 0) // the argument of the log is negative
|
|
789
|
+
then
|
|
790
|
+
Result := Infinity
|
|
791
|
+
else begin
|
|
792
|
+
Result := ln(x1/x2) / ln(q);
|
|
793
|
+
end;
|
|
794
|
+
end;
|
|
795
|
+
end;
|
|
796
|
+
|
|
797
|
+
function Payment(ARate: double; NPeriods: Integer;
|
|
798
|
+
APresentValue, AFutureValue: double; APaymentTime: TPaymentTime): double;
|
|
799
|
+
var
|
|
800
|
+
q, qn, factor: double;
|
|
801
|
+
begin
|
|
802
|
+
if ARate = 0 then
|
|
803
|
+
Result := -(AFutureValue + APresentValue) / NPeriods
|
|
804
|
+
else begin
|
|
805
|
+
q := 1.0 + ARate;
|
|
806
|
+
qn := power(q, NPeriods);
|
|
807
|
+
factor := (qn - 1) / (q - 1);
|
|
808
|
+
if APaymentTime = ptStartOfPeriod then
|
|
809
|
+
factor := factor * q;
|
|
810
|
+
Result := -(AFutureValue + APresentValue * qn) / factor;
|
|
811
|
+
end;
|
|
812
|
+
end;
|
|
813
|
+
|
|
814
|
+
function PresentValue(ARate: double; NPeriods: Integer;
|
|
815
|
+
APayment, AFutureValue: double; APaymentTime: TPaymentTime): double;
|
|
816
|
+
var
|
|
817
|
+
q, qn, factor: double;
|
|
818
|
+
begin
|
|
819
|
+
if ARate = 0.0 then
|
|
820
|
+
Result := -AFutureValue - APayment * NPeriods
|
|
821
|
+
else begin
|
|
822
|
+
q := 1.0 + ARate;
|
|
823
|
+
qn := power(q, NPeriods);
|
|
824
|
+
factor := (qn - 1) / (q - 1);
|
|
825
|
+
if APaymentTime = ptStartOfPeriod then
|
|
826
|
+
factor := factor * q;
|
|
827
|
+
Result := -(AFutureValue + APayment*factor) / qn;
|
|
828
|
+
end;
|
|
829
|
+
end;
|
|
830
|
+
|
|
831
|
+
{ ---------------------------------------------------------------------
|
|
832
|
+
Miscellaneous
|
|
833
|
+
---------------------------------------------------------------------}
|
|
834
|
+
|
|
835
|
+
function IfThen(val: boolean; const ifTrue: integer; const ifFalse: integer): integer;
|
|
836
|
+
|
|
837
|
+
begin
|
|
838
|
+
if val then result:=iftrue else result:=iffalse;
|
|
839
|
+
end;
|
|
840
|
+
|
|
841
|
+
function IfThen(val: boolean; const ifTrue: double; const ifFalse: double): double;
|
|
842
|
+
|
|
843
|
+
begin
|
|
844
|
+
if val then result:=iftrue else result:=iffalse;
|
|
845
|
+
end;
|
|
846
|
+
|
|
847
|
+
function CompareValue(const A, B : Integer): TValueRelationship;
|
|
848
|
+
|
|
849
|
+
begin
|
|
850
|
+
result:=GreaterThanValue;
|
|
851
|
+
if a=b then
|
|
852
|
+
result:=EqualsValue
|
|
853
|
+
else
|
|
854
|
+
if a<b then
|
|
855
|
+
result:=LessThanValue;
|
|
856
|
+
end;
|
|
857
|
+
|
|
858
|
+
function CompareValue(const A, B: NativeLargeInt): TValueRelationship;
|
|
859
|
+
|
|
860
|
+
begin
|
|
861
|
+
result:=GreaterThanValue;
|
|
862
|
+
if a=b then
|
|
863
|
+
result:=EqualsValue
|
|
864
|
+
else
|
|
865
|
+
if a<b then
|
|
866
|
+
result:=LessThanValue;
|
|
867
|
+
end;
|
|
868
|
+
|
|
869
|
+
function CompareValue(const A, B: NativeLargeUInt): TValueRelationship;
|
|
870
|
+
|
|
871
|
+
begin
|
|
872
|
+
result:=GreaterThanValue;
|
|
873
|
+
if a=b then
|
|
874
|
+
result:=EqualsValue
|
|
875
|
+
else
|
|
876
|
+
if a<b then
|
|
877
|
+
result:=LessThanValue;
|
|
878
|
+
end;
|
|
879
|
+
|
|
880
|
+
function CompareValue(const A, B: Double; delta: Double): TValueRelationship;
|
|
881
|
+
begin
|
|
882
|
+
result:=GreaterThanValue;
|
|
883
|
+
if abs(a-b)<=delta then
|
|
884
|
+
result:=EqualsValue
|
|
885
|
+
else
|
|
886
|
+
if a<b then
|
|
887
|
+
result:=LessThanValue;
|
|
888
|
+
end;
|
|
889
|
+
|
|
890
|
+
function MaxIntValue(const AData: array of Integer): Integer;
|
|
891
|
+
var
|
|
892
|
+
lCount: Integer;
|
|
893
|
+
begin
|
|
894
|
+
Result := AData[Low(AData)];
|
|
895
|
+
for lCount := Low(AData) + 1 to High(AData) do
|
|
896
|
+
begin
|
|
897
|
+
if Result < AData[lCount] then
|
|
898
|
+
Result := AData[lCount];
|
|
899
|
+
end;
|
|
900
|
+
end;
|
|
901
|
+
|
|
902
|
+
end.
|
|
903
|
+
|