News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Division question

Started by Ghirai, April 02, 2006, 01:19:24 AM

Previous topic - Next topic

Ghirai

How do i divide a qword by another qword (which is split in 2 dword vars)?

Thanks.
MASM32 Project/RadASM mirror - http://ghirai.com/hutch/mmi.html

raymond

The easiest way is to do it with the FPU.


fild  qword1
fild  qword2
fdiv
fistp qword3


The answer with the above code would be rounded to the nearest integer with the default Control Word of the FPU. If you want a truncated answer (as you would with integer maths on the CPU), you would need to modify the Control Word for truncating before you perform the division.

Then, if you also want the remainder, you would need to add a few more instructions.

Note that the FPU considers ALL integer variables as SIGNED integers.

Raymond
When you assume something, you risk being wrong half the time
http://www.ray.masmcode.com

Ghirai

MASM32 Project/RadASM mirror - http://ghirai.com/hutch/mmi.html

Ghirai

Hmmm, am i supposed to use FPREM?
MASM32 Project/RadASM mirror - http://ghirai.com/hutch/mmi.html

dsouza123

A 64 bit unsigned integer version using only the CPU
no FPU, MMX, 3DNow, SSE, SSE2, SSE3 instructions.

Covers all the cases I could think of:
Div by 0, Div by 1, 32bit / 32bit, 64bit / 32bit, 64bit / 64bit.
Produces both quotient and remainder.

Displays two messageboxes,
with numerator and denominator,  ( real names are dividend and divisor but I was used their fraction names )
with quotient and remainder.

Deals with issue of 64 bit / 32bit with 32bit < upper half of 64bit (high dword), to prevent an exception.

[attachment deleted by admin]

dsouza123

Minor revision, will show numerator and denominator then the error message Division by zero
if the denominator is zero.

Also has more of the test values I used, for the different combinations,
they are commented out, but can easily be reactivated
by switching between commented versions of num and den.

No changes to calculation code.


align 16
  num     dq 1152921504606846978    ; 2^60 + 2      64 / 64  with reminder
  den     dq    1125899906842627    ; 2^50 + 3

;   num     dq 1152921504606846978    ; 2^60 + 2      64 /  0  Error division by zero
;   den     dq                   0    ; 0

;   num     dq 1152921504606846978    ; 2^60 + 2      64 /  1  Division by one
;   den     dq                   1    ; 1

;   num     dq 1152921504606846976    ; 2^60          64 / 64  no remainder
;   den     dq    1125899906842624    ; 2^50

;   num     dq 1152921504606846977    ; 2^60 + 1      64 / 32  with remainder
;   den     dq                   8    ; 8

;   num     dq                 101    ; 101           32 / 32  with remainder
;   den     dq                   5    ; 5

  quo     dq                   0
  rem     dq                   0

[attachment deleted by admin]

dsouza123

Revisions:

Removed separate 32 bit / 32 bit it is case of 64 bit / 32 bit.
Put special cases of 32 bit / 32 bit in for num == den, num < den
in the 64 bit / 32 bit, they skip the division.

Included both 64 bit / 64 bit and 32 bit / 32 bit cases of num == den.

Cleaned up 64 bit / 64 bit.

Added commented test conditions.

[attachment deleted by admin]

dsouza123

Added a FPU version (63 bits) calculates both the quotient and remainder qwords
with results in a third messagebox for comparison with the CPU version.

Comments on what is done. 
Uses finit, but doesn't modify the Control Word for truncating.
Uses the fprem to help remove 0.999, the fractional part.

load num
load den
quofp = num / den
duplicate quofp
remove fractional part of quofp
duplicate quofp
store quofp
load den
quofp * den
load num
remfp = num - (quofp * den)
store remfp

[attachment deleted by admin]

Ghirai

Thanks a lot for the comprehensive answer and code :U
MASM32 Project/RadASM mirror - http://ghirai.com/hutch/mmi.html