1
{ **********************************************************************
3
**********************************************************************
4
Mathematical functions for TPMATH
5
(Assembler version for Pentium II/III with FPC)
6
********************************************************************** }
9
{ Bibliotheque mathematique pour utilisation du coprocesseur flottant
12
----------------------------------------------------------------------
13
Unite d'origine : MATH387.PAS, disponible dans MATHLIB2.ZIP
14
(http://wcarchive.cdrom.com/pub/delphi_www/)
15
Adapte aux pentiums II/III et complete par P. NOGARET (2000)
16
---------------------------------------------------------------------- }
20
{***********************************************************************}
21
{* function fexp(x : Float): Float;assembler; *}
22
{***********************************************************************}
23
{* Fonction d�velopp�e � partir du document de Agner Fog *}
24
{* www.agner.org/assem *}
25
{***********************************************************************}
26
{* retourne e^x, par la methode e^x = 2^(x.log2(e)) *}
27
{* 2^z = 2^f.2^i avec f = frac(z) and i = int(z) *}
28
{* 2^f is computed with F2XM1, *}
29
{* 2^i pourrait �tre calcul� avec FSCALE mais cette instruction *}
30
{* est tr�s lente 56 micro-ops sur un pentium II *}
31
{* pour la m�thode utilis� pour calculer 2^i voir Agner Fog *}
32
{***********************************************************************}
39
{* 2^(z - round(z)) - 1 - *}
40
{* 1 2^(z - round(z)) - 1 *}
41
{* 2^(z - round(z)) - *}
42
{* temp:=2^i 2^f:=2^(z - round(z)) *}
44
{***********************************************************************}
45
function fexp(x : Float): Float;assembler;
54
MOV DWORD PTR [temp], 00000000H
55
MOV DWORD PTR [temp+4],80000000H
59
MOV DWORD PTR [temp+8],EAX
68
{***********************************************************************}
69
{* function fexp2(x : Float): Float; assembler; *}
70
{***********************************************************************}
71
{* Fonction d�velopp�e � partir du document de Agner Fog *}
72
{* www.agner.org/assem *}
73
{***********************************************************************}
74
{* retourne 2^x par la methode 2^z = 2^f.2^i *}
75
{* avec f = frac(z) and i = int(z) *}
76
{* 2^f is computed with F2XM1, *}
77
{* 2^i pourrait �tre calcul� avec FSCALE mais cette instruction *}
78
{* est tr�s lente 56 micro-ops sur un pentium II *}
79
{* pour la m�thode utilis� pour calculer 2^i voir Agner Fog *}
80
{***********************************************************************}
86
{* 2^(z - round(z)) - 1 - *}
87
{* 1 2^(z - round(z)) - 1 *}
88
{* 2^(z - round(z)) - *}
89
{* temp:=2^i 2^f:=2^(z - round(z)) *}
91
{***********************************************************************}
92
function fexp2(x : Float): Float; assembler;
99
MOV DWORD PTR [temp], 00000000H
100
MOV DWORD PTR [temp+4],80000000H
102
MOV EAX, round_z { round_zmax := 16384 }
104
MOV DWORD PTR [temp+8],EAX
112
{***********************************************************************}
113
{* function fexp10(x : Float): Float; assembler; *}
114
{***********************************************************************}
115
{* Fonction d�velopp�e � partir du document de Agner Fog *}
116
{* www.agner.org/assem *}
117
{***********************************************************************}
118
{* retourne 10^x, par la methode 10^x = 2^(x.log2(10)) *}
119
{* 2^z = 2^f.2^i with f = frac(z) and i = int(z) *}
120
{* 2^f is computed with F2XM1 *}
121
{* 2^i pourrait �tre calcul� avec FSCALE mais cette instruction *}
122
{* est tr�s lente 56 micro-ops sur un pentium II *}
123
{* pour la m�thode utilis� pour calculer 2^i voir Agner Fog *}
124
{***********************************************************************}
128
{* z:=x.log2(10) - *}
131
{* 2^(z - round(z)) - 1 - *}
132
{* 1 2^(z - round(z)) - 1 *}
133
{* 2^(z - round(z)) - *}
134
{* temp:=2^i 2^f:=2^(z - round(z)) *}
136
{***********************************************************************}
137
function fexp10(x : Float): Float; assembler;
146
MOV DWORD PTR [temp], 00000000H
147
MOV DWORD PTR [temp+4],80000000H
151
MOV DWORD PTR [temp+8],EAX
159
function fln(x : Float): Float; assembler;
160
{ retourne le logarithme naturel de x, utilise
161
la methode loge(x) = loge(2).log2(x) }
162
{ pas de verification du domaine de definition (x < 0) }
166
FYL2X { ln(2).log2(x) - }
169
function flog2(x : Float): Float; assembler;
170
{ retourne le logarithme de base 2 de x }
171
{ pas de verification du domaine de definition (x < 0) }
178
{***********************************************************************}
179
{* function flog10(X : Float) : Float; *}
180
{***********************************************************************}
181
{* Compute a common (base 10) logarithm. If X is near 1.0, then we *}
182
{* use the FYL2XP1 instruction instead of FYL2X. "Near" means between *}
183
{* 1.0 and 1+Sqrt(2)/2. We use an approximation for Sqrt(2)/2, so we *}
184
{* don't have to compute it. The exact value isn't important, since *}
185
{* FYL2X works fine for values near the transition. *}
186
{***********************************************************************}
187
function flog10(x : Float): Float; assembler;
189
HalfSqrt2p1: Extended = 1.7071;
194
fcomp ST(1) { if (X < 1.0) }
196
fld HalfSqrt2p1 { push 1.707 }
197
fcomp ST(1) { if (X > 1.707) }
199
fld1 { X is small, so subtract 1.0 }
200
fsubrp { X := X - 1.0 }
201
fyl2xp1 { Log10(2) * Log2(X+1) }
203
@@1: { X is not near 1.0 }
204
fyl2x { Log10(2) * Log2(X) }
208
{***********************************************************************}
209
{* function fsin(X : Float) : Float; *}
210
{***********************************************************************}
211
{* if x < pi.2^62, then C2 is set to 0 and ST = sin(x) *}
212
{* else C2 is set to 1 and ST = x *}
213
{* no check range validity is performed in this function *}
214
{***********************************************************************}
215
function fsin(X : Float) : Float; assembler;
221
{***********************************************************************}
222
{* function fcos(X : Float) : Float; *}
223
{***********************************************************************}
224
function fcos(X : Float) : Float; assembler;
230
{***********************************************************************}
231
{* function ftan(X : Float) : Float;assembler; *}
232
{***********************************************************************}
233
function ftan(X : Float) : Float; assembler;
237
FSTP ST(0) { tan(x) - }
240
{***********************************************************************}
241
{* function farctan(X : Float) : Float; *}
242
{***********************************************************************}
243
function farctan(x : Float): Float; assembler;
247
FPATAN { atan(x/1) - }
250
{***********************************************************************}
251
{* function farctan2(Y, X : Float) : Float; *}
252
{***********************************************************************}
253
function farctan2(y, x : Float): Float; assembler;
254
{ retourne arctan (y / x) }
258
FPATAN { atan(y/x) - }
261
{***********************************************************************}
262
{* function farcsin(X : Float) : Float; *}
263
{***********************************************************************}
264
{* retourne l'arcsin de x *}
265
{* methode : ________ *}
266
{* arcsin(x) = arctan( x / V 1 - x.x ) *}
267
{* no range validity check is performed in this function |x| > 1 *}
268
{***********************************************************************}
269
{* ST(0) ST(1) ST(2) *}
277
{***********************************************************************}
278
function farcsin(x : Float): Float; assembler;
289
{***********************************************************************}
290
{* function farccos(x : Float): Float; assembler; *}
291
{***********************************************************************}
292
{* retourne l'arccos de x *}
293
{* methode : ________ *}
294
{* arccos(x) = arctan( V 1 - x.x / x) *}
295
{* pas de controle de domaine de definition |x| > 1 *}
296
{***********************************************************************}
297
{* ST(0) ST(1) ST(2) *}
306
{***********************************************************************}
307
function farccos(x : Float): Float; assembler;
319
{***********************************************************************}
320
{* function fsinh(X : Float) : Float; *}
321
{***********************************************************************}
322
{* retourne le sinus hyperbolique de l'argument *}
323
{* sh(x) = [exp(x) - exp(-x)] / 2 *}
324
{* methode : z = exp(x), ch(x) = 1/2 (z - 1/z) *}
325
{* z = 2^y, y = x.log2(e), *}
326
{* z = 2^f.2^i, f = frac(y), i = int(y) *}
327
{* 2^f est calcul� avec F2XM1, 2^i sans FSCALE *}
328
{***********************************************************************}
329
{* ST(0) ST(1) ST(2) *}
332
{* z:=x.log2(e) - - *}
334
{* z - round(z) - - *}
335
{* 2^(z - round(z)) - 1 - - *}
336
{* 1 2^(z - round(z)) - 1 - *}
337
{* 2^(z - round(z)) - - *}
338
{* temp:=2^i 2^f:=2^(z - round(z)) - *}
346
{***********************************************************************}
347
function fsinh(x : float): float; assembler;
349
one_half : float = 0.5;
358
MOV DWORD PTR [temp], 00000000H
359
MOV DWORD PTR [temp+4],80000000H
363
MOV DWORD PTR [temp+8],EAX
377
{***********************************************************************}
378
{* function fcosh(X : Float) : Float; *}
379
{***********************************************************************}
380
{* retourne le cosinus hyperbolique de l'argument *}
381
{* ch(x) = [exp(x) + exp(-x)] / 2 *}
382
{* methode : z = exp(x), ch(x) = 1/2 (z + 1/z) *}
383
{* z = 2^y, y = x.log2(e), *}
384
{* z = 2^f.2^i, f = frac(y), i = int(y) *}
385
{* 2^f est calcul� avec F2XM1, 2^i sans FSCALE *}
386
{***********************************************************************}
387
{* st(0) st(1) st(2) *}
393
{* 2^(z - round(z)) - 1 - *}
394
{* 1 2^(z - round(z)) - 1 *}
395
{* 2^(z - round(z)) - *}
396
{* temp:=2^i 2^f:=2^(z - round(z)) *}
404
{***********************************************************************}
405
function fcosh(x : float): float; assembler;
407
one_half : float = 0.5;
416
MOV DWORD PTR [temp], 00000000H
417
MOV DWORD PTR [temp+4],80000000H
421
MOV DWORD PTR [temp+8],EAX
435
{***********************************************************************}
436
{* function ftanh(X : Float) : Float; *}
437
{***********************************************************************}
438
{* retourne la tangente hyperbolique de l'argument *}
439
{* th(x) = sh(x) / ch(x) *) *}
440
{* th(x) = [exp(x) - exp(-x)] / [exp(x) + exp(-x)] *}
441
{* methode : z = exp(x), ch(x) = (z - 1/z) / (z + 1/z) *}
442
{* z = 2^y, y = x.log2(e), *}
443
{* z = 2^f.2^i, f = frac(y), i = int(y) *}
444
{* 2^f est calcul� avec F2XM1, 2^i sans FSCALE *}
445
{***********************************************************************}
446
{* st(0) st(1) st(2) *}
452
{* 2^(z - round(z)) - 1 - *}
453
{* 1 2^(z - round(z)) - 1 *}
454
{* 2^(z - round(z)) - *}
455
{* temp:=2^i 2^f:=2^(z - round(z)) *}
463
{***********************************************************************}
464
function ftanh(x : float): float; assembler;
466
one_half : float = 0.5;
475
MOV DWORD PTR [temp], 00000000H
476
MOV DWORD PTR [temp+4],80000000H
480
MOV DWORD PTR [temp+8],EAX
494
{***********************************************************************}
495
{* function farcsinh(X : Float) : Float; *}
496
{***********************************************************************}
497
{* retourne l'arc sinus hyperbolique de l'argument *}
499
{* arg sh(x) = ln ( x + V x.x + 1 ) *}
500
{***********************************************************************}
501
{* ST(0) ST(1) ST(2) ST(3) *}
507
{* x.x + 1 x ln(2) - *}
508
{* sqrt(x.x+1) x ln(2) - *}
509
{* x + z ln(2) - - *}
510
{* arg_sh(x) - - - *}
511
{***********************************************************************}
512
function farcsinh(x : float): float; assembler;
525
{***********************************************************************}
526
{* function farccosh(X : Float) : Float; *}
527
{***********************************************************************}
528
{* retourne l'arc cosinus hyperbolique de l'argument *}
530
{* arg ch(x) = ln ( x + V x.x - 1 ) x >=1 *}
531
{***********************************************************************}
532
{* ST(0) ST(1) ST(2) ST(3) *}
538
{* x.x - 1 x ln(2) - *}
539
{* sqrt(x2-1) x ln(2) - *}
540
{* x + z ln(2) - - *}
541
{* arg_ch(x) - - - *}
542
{***********************************************************************}
543
function farccosh(x : float): float; assembler;
556
{***********************************************************************}
557
{* function farctanh(X : Float) : Float; *}
558
{***********************************************************************}
559
{* retourne l'arc tangente hyperbolique de l'argument *}
560
{* arg th(x) = 1/2 ln [ (1 + x) / (1 - x) ] *}
561
{***********************************************************************}
562
{* ST(0) ST(1) ST(2) ST(3) *}
567
{* 1 x 1 + x ln(2) *}
568
{* 1 - x 1 + x ln(2) - *}
569
{* 1+x/1-x ln(2) - - *}
571
{***********************************************************************}
572
function farctanh(x : float): float; assembler;