[fpc-devel] Math.DivMod results should be signed
k at i.fredriksen.net
k at i.fredriksen.net
Wed Nov 8 17:04:23 CET 2006
I just read your posting on Delphi's DivMod. It doesn't work very well, not on LongInt (Integer) values and negatives, not on Delphi 6, that I'm using, anyway.
I wrote an alternative that handles LongInt and negatives. It takes only Integer parameters. It's a function, rather than a procedure. You pass Value (the number that you will divide), Divisor by value. You pass Remainder (Mod-value) by ref, and it returns the Result (Div-Value).
It is almost as fast as DivMod, I have an alternative SmallInt-version that matches DivMod in speed, but handles negatives correctly.
function DivWithRemainder(Value, Divisor: Integer; var Remainder: Integer): Integer;
{
In:
EAX = Value
ECX = @Remainder
EDX = Divisor
Out:
EAX = Result
ECX = @Remainder
}
asm
PUSH EBX { Save EBX - this register is not free to use }
MOV EBX , EDX { Copy Divisor to EBX, using it as a store }
TEST EAX , $80000000 { Test if Value is signed }
JNZ @Signed { If Value is negative, prepare signed EDX }
MOV EDX , 0 { If Value is positive, prepare unsigned EDX (Clear it) }
@Continue:
IDIV EBX { Divides Value (actually EDX + EAX (64 bit)) by EBX. Result -> EAX, remainder -> EDX }
MOV [ECX], EDX { Copies EDX to ECX^ (Remainder) }
POP EBX { Restore EBX }
RET
@Signed:
MOV EDX , -1 { Fill EDX with $FFFFFFFF if Value was signed }
JMP @Continue
end;
--
This message was sent on behalf of k at i.fredriksen.net at openSubscriber.com
http://www.opensubscriber.com/message/fpc-devel@lists.freepascal.org/3622483.html
More information about the fpc-devel
mailing list