[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;
     EAX = Value
     ECX = @Remainder
     EDX = Divisor

     EAX = Result
     ECX = @Remainder
  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) }
  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 }
  MOV  EDX  , -1        { Fill EDX with $FFFFFFFF if Value was signed }
  JMP @Continue

This message was sent on behalf of k at i.fredriksen.net at openSubscriber.com

More information about the fpc-devel mailing list