Re: 64bit/64bit fixed point division?



Phil Carmody wrote:
"Maarten Kronenburg" <spamtrap@xxxxxxxxxx> writes:
Phil,
The mantissa for extended precision 80-bit floating point
is the full 64-bit, only bit number 63 is always 1.
The sign bit is bit number 79, see for example
http://babbage.cs.qc.edu/courses/cs341/IEEE-754references.html
and the book The Intel Microprocessors by Barry Brey.
So you can put a 64-bit integer into an extended precision
80-bit floating point without loss of precision.

I know. The FPU's fine, it's the interface from FP to integer
that's the problem. You can't (just) use a FISTP though.
(Unless you know that the answer is unique modulo 2^64.)

Loading the input values is relatively easy, OK?

The fastest might actually be to always load it as a signed 63-bit integer, and then use that "sign" bit to add either 0.0 or 2^63 to the initial result.

Assuming such maximally large inputs are very rare, it would probably be faster to use an actual branch around the fixup add instead:

fild qword ptr [a]
test byte ptr [a+7],80h
jz a_done
fadd dword ptr [two_to_64]
a_done:
fild qword ptr [b]
test byte ptr [b+7],80h
jz b_done
fadd dword ptr [two_to_64]
b_done:
fdivp st(1), st
fmul dword ptr [two_to_32] ;; Convert back to 32:32 fixed point!

At this point we have several possible outcomes, all positive:

a) Underflow: The result is less than 1 (corresponding to 2^-31)
Storing this as an integer (with truncation) will result in zero, which is correct.

b) In-range (2^63 > result >= 1): Storing as integer is OK

c) In-range but too large for 64-bit int (2^64 > result >= 2^63): Storing as integer will overflow.

d) Overflow (result >= 2^64): This cannot be stored as a 64-bit unsigned value, and must be handled by higher level sw.

I.e. only case (c) is hard, and it can be handled relatively easy by testing the result against 2^63, and if possible, subtract 2^64 to convert into an in-range 64-bit integer value which when stored will have the correct bitpattern, similar to my input adjustment:

if (result >= two_to_63) {
if (result >= two_to_64)
trap(OVERFLOW);
result -= two_to_64;
}

Terje
--
- <Terje.Mathisen@xxxxxxxxxxxxx>
"almost all programming can be viewed as an exercise in caching"

.



Relevant Pages

  • Re: 64bit/64bit fixed point division?
    ... The mantissa for extended precision 80-bit floating point ... So you can put a 64-bit integer into an extended precision ... Newton-Raphson (which is faster at 32 bits, ... FILD qword ptr ...
    (comp.lang.asm.x86)
  • Re: 64bit/64bit fixed point division?
    ... and use fld tword where edx is the address. ... Only then you must also write/read the exponent, ... The mantissa for extended precision 80-bit floating point ...
    (comp.lang.asm.x86)
  • Re: comparison on non-integer types
    ... of x gets pushed into a floating point register and the second copy ... That's an operating system bug, ...
    (comp.lang.c)
  • Re: 64bit/64bit fixed point division?
    ... The mantissa for extended precision 80-bit floating point ... So you can put a 64-bit integer into an extended precision ... "Home taping is killing big business profits. ...
    (comp.lang.asm.x86)