Is there a better way to do a safe division, eg. not devide by zero?

Mov esi, aCount
or esi, esi
JZ @@3 // Wenn aCount 0 ist, sind wir fertig
PUSH EBX // EBX Retten - macht Delphi nicht selber!
PUSH ESI
Mov edx, aSrcPointer1
Mov ebx, aSrcPointer2
Mov ecx, aDestPointer
SHL ESI, 3 // count mit 3 Multiplizieren
fld qword ptr // ScaleFactorladen
@@1:
fld qword ptr // Divisor laden
fldz // 0 laden zum vergleichen
FUCOM st(1); // ST(0) und 1 vergleichen.....
FSTSW AX; // Compare nach AX
SAHF; // in Flags laden
JZ @@STORE; // Store 0 - bei NaN oder 0
fld st(2); // ScaleFactor nach ST(0)
fmul qword ptr // SrcVector2 Multiplizieren
FDIVRP ST(2), ST; // Reziproke teilung Erg: in ST(0)
FXCH ST(1); // Ergenis mit TOS tauschen
@@STORE:
fstp qword ptr // in Destvector speichern
// Laut Doku (von Intel) d?rfte es den folgenden Befehl nicht geben, laut
// Amd gibt es den Befehl in jedem (!) x86 Prozessor - getestet und f?r
// gut befunden.....
DB $DF DB $C0 // FFREEP ST(0); // TOS l?schen & Stack Increment
// FINCSTP // Stack incrementieren
sub esi, 8 // 8 abziehen, wegen Doublesize
jnz @@1
POP ESI
POP EBX
FFREE ST(0)
@@3:
FWAIT
Posted on 2004-11-05 09:13:46 by abrosda
1. You can use FTST instead of FLDZ/FUCOM sequance.
2. Or, you may implement your own exception handler, in which you recover from div by 0 and forget about it in the main line of code. For example, just warn the user about div by 0 and move on, assuming that 0 does not come in unless the user or the programmer drops the ball.

Besides, why do you use that slow FFREE?
Posted on 2004-11-06 00:44:50 by Starless
Regardless if FFREE is slow or not, it is entirely useless in this context. If you don't need the st(0) value anymore, you should pop it off with:

fstp st

Raymond
Posted on 2004-11-06 15:22:48 by Raymond
Hi,

ok I did not knew about fstp st (that sequence did not come in my mind. Will test it :-).

I can't warn the User about the Div by Zero, it is a server side Application which calcs values.

In an older version I was dealing with NaN but NaN are slow on Intel Processors and I have to replace the NaN later with a 0.... Salesman are strange people....

What the routine should do: Test if the value is zero or NaN then the result should be 0, else Result := Value/DivValue


Greetings and thanks for the advise.
Posted on 2004-11-08 03:23:15 by abrosda
Sorry for delay. Been on the road for a few days.

Unlike the CPU, division by 0 on the FPU is a valid operation (returning INFINITY as the result if the numerator is a valid finite number) and will not crash the program. However, it does raise the Zero-divide exception flag of the Status Word.

Your best option should be to simply perform the division without any checking of the supplied parameters. Then check the Status Word for the Invalid-operation and Zero-divide flags. If either one is raised, you then take whatever action is required (such as replacing the result with 0).

Don't forget to include the FCLEX instruction immediately before each division to clear any exception flag raised by previous operations.

Raymond
Posted on 2004-11-10 20:15:20 by Raymond