Newsgroups : Borland : borland.public.delphi.rtl.win32 : 2005 Aug : Division of Quad by Double...
| Subject: | Division of Quad by Double... |
| Posted by: | "Ian Boyd" (ian.borlandnews008@zunblvlda1.dyndns.org.spamsucks) |
| Date: | Tue, 9 Aug 2005 22:49:40 |
i'm doing multiprecision division. At it's basic level, i must concatenate
two unsigned 32-bit values (LongWords) and
divided by another 32-bit unsigned value (LongWord).
It is guaranteed that the result of the division will be <= 32 bits
(LongWord)
So, my pseudo code is:
function QuadDivDouble(x1, x0: LongWord; y: LongWord): LongWord;
{ Unsigned divide x1:x0 by y }
begin
{$RANGECHECKS OFF}
Result := ((Int64(x1) shl 32) or x0) div y;
{$RANGECHECKS ON}
end;
procedure TForm1.Button1Click(Sender: TObject);
var
x1, x0, y, R: LongWord;
begin
{calculate $FFFFFFFE00000001 div $FFFFFFFF }
x1 := $FFFFFFFE;
x0 := $00000001;
y := $FFFFFFFF;
R := QuadDivDouble(x1, x0, y);
//Correct answer is $FFFFFFFF
//Delphi gives answer $FFFFFFFE
Assert(R = $FFFFFFFF, 'Nope.');
end;
But this doesn't work, i assume because Int64 is signed. But i don't know
how to how to fool Delphi into doing the division unsigned. i'm sure it
cannot be done in Delphi, and you have to use assember.
i have no practical experience with asm, but i'll pretend it's something
like this:
procedure QuadDivMod(var x0, x1: LongWord; y: LongWord);
{ Unsigned divide x1:x0 by doubleword y
x0 := Quotient
x1 := Remainder
Intel says:
DIV is Unsigned divide EDX:EAX by r/m32 doubleword;
EAX <- Quotient, EDX <- Remainder }
asm
{ i assume
x0 is passed in EAX
x1 is passed in EDX,
my syntax is valid}
DIV y
end;
and call it with
procedure TfrmMain.Button1Click(Sender: TObject);
var
x1, x0, y, R: LongWord;
begin
{calculate $FFFFFFFE00000001 div $FFFFFFFF = $FFFFFFFF
i.e. 18446744065119617025 div 4294967295 = 4294967295}
x1 := $FFFFFFFE;
x0 := $00000001;
y := $FFFFFFFF;
QuadDivMod(x0, x1, y);
//answer is $FFFFFFFF
Assert(x1 = $FFFFFFFF, 'Nope.');
end;
Which, amazingly enough, compiles; but is wrong. Passing x1 and x0 as var
causes
EAX and EDX to contain the pointers to the values. And i don't know the
proper
techniques for asm.
So can someone help me out here?