Re: FastCode : Exponential



Hi Michael Moreno,

I wrote this function, the number of loop changes the precision of the calculation. There is no need of any initialisations.

The gain depends on the precision:
3.6% -> 40% faster
0.35% -> 31% faster
0.026% -> 16% faster

var
Middle: Extended = 0.0138999122173; // The same precision around -1 and around 1 (minimize the order)
MiddlePower: Extended = 1.009681248; // 2**Middle
Coeff: array [0..10] of Extended = (
1.0000000000000,
0.6931471805599,
0.2402265069591,
0.0555041086648, // (ln 2)**N / N!
0.0096181291076,
0.0013333558146,
0.0001540353039,
0.0000152527338,
0.0000013215487,
0.0000001017809,
0.0000000070549 );


  FastExpOrder: Integer = 2;
  // Order = 1  ==> Precision = 3.63200671587156E-0002
  // Order = 2  ==> Precision = 3.50748436802649E-0003
  // Order = 3  ==> Precision = 2.56652819891839E-0004
  // Order = 4  ==> Precision = 1.51012978338938E-0005
  // Order = 5  ==> Precision = 7.42599281103502E-0007
  // Order = 6  ==> Precision = 3.13216816747873E-0008
  // Order = 7  ==> Precision = 1.12102436236822E-0009
  // Order = 8  ==> Precision = 3.92020589167624E-0011
  // Order = 9  ==> Precision = 3.92020589167624E-0011
  // Order = 10 ==> Precision = 3.92020589167624E-0011

function FastExp(const Value: Extended): Extended;
asm
  FLD     Value
  FLDL2E
  FMUL
  FLD     ST(0)
  MOV     ECX,   FastExpOrder
  FRNDINT
  FSUB    ST(1), ST(0)
  FXCH    ST(1)
  FLD     Middle
  MOV     EDX,   10
  FSUBP   ST(1), ST(0)
  FLD1
  FLD     ST(1)
  // 2**a = 2**Middle * ( 1 +  ln(2)     * (a-Middle)    /1!
  //                        + (ln(2))**2 * (a-Middle)**2 /2!
  //                           ...
  //                        + (ln(2))**N * (a-Middle)**N /N! )
@@Loop:
  FLD     Extended PTR [Coeff + EDX]
  FMUL    ST(0), ST(1)
  FADDP   ST(2), ST(0)
  DEC     ECX
  JZ      @@End
  ADD     EDX,   10
  FMUL    ST(0), ST(2)
  JMP     @@Loop
@@End:
  FSTP    ST(2)
  FSTP    ST(1)
  FLD     MiddlePower
  FMUL
  FSCALE       // e**x = 2**(x * log2(e))
  FSTP    ST(1)
end;

Cheers,

Florent
.



Relevant Pages

  • RE: Jump to specific record in recordset
    ... the outer Do Loop, I always return to the first record of the inner recordset ... For Each fld In tdf.Fields ... Set rsCurrent = MyDB.OpenRecordset("SELECT * FROM qryOrderProductsBase ...
    (microsoft.public.access.modulesdaovba)
  • Re: Count VB
    ... >Your code doesn't loop through the field names, ... > Dim fld As DAO.Field ... >> Function CountBlanks(FiledName As String, ...
    (microsoft.public.access.modulesdaovba)
  • Re: How to make Delphi code quicker
    ... I am aware that drawing pixel by pixel is slow, ... the pixel drawing may slow the thing down a lot. ... fld tbyte ptr [eax] ... fstp st ...
    (borland.public.delphi.language.basm)
  • Re: Veiwing Datasets in Debug Mode
    ... Chris Hanscom - Microsoft MVP ... Loop through the rs and print each fld, ... >> Is there a way to view the contents of a Dataset in Debug mode? ...
    (microsoft.public.vb.bugs)
  • Re: Fastcode Complex Number Polar Addition B&V 0.3
    ... added an fwait in each of the functions to correct this. ... fld X.Amplitude ... fstp Result.Amplitude ...
    (borland.public.delphi.language.basm)