Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

'fist' FPU problem with unsigned 32Bit integers

74 views
Skip to first unread message

Markus Solbach

unread,
Oct 18, 1995, 3:00:00 AM10/18/95
to
I am new in floating point programming and encountered the following
problem.
When I try to convert a floating point number to an unsigned integer
using the 'fist' or 'fistp' instruction I get a fpu exception if the
number that has to be converted is greater than 2^31. This means that
the highest bit (sign bit) in the integer converted number must be set.
I guess the fpu generates an overflow exception. Am I right?
My solution to this problem is to store a qword instead of a dword but
I have not tried it yet. Anyway my question is : How can I convert a
floating point value to a 32-bit unsigned integer without qword stuff.

Thanks in advance
Markus

--
/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\
/ Markus Solbach <m.so...@qcont.ndh.com> ~~~~~~~~~~~~~~~~~~~~~~~~~~~\
\ Weberstrasse 1, 53844 Troisdorf, Germany Voice: +049-2241-409813 \
\_______________________________________________________________________/

jkee...@vnet.ibm.com

unread,
Oct 22, 1995, 3:00:00 AM10/22/95
to

Subtract 2^31 before storing the number out and add 2^31 after storing the
number.

John Keenleyside
VisualAge C++ Development
#include <std-disclaimer> Email: jkee...@vnet.ibm.com


Paul Schlyter

unread,
Oct 23, 1995, 3:00:00 AM10/23/95
to
In article <5w52z...@qcont.ndh.com>,

Markus Solbach <m.so...@qcont.ndh.com> wrote:

> When I try to convert a floating point number to an unsigned integer
> using the 'fist' or 'fistp' instruction I get a fpu exception if the
> number that has to be converted is greater than 2^31. This means that
> the highest bit (sign bit) in the integer converted number must be set.
> I guess the fpu generates an overflow exception. Am I right?
> My solution to this problem is to store a qword instead of a dword but
> I have not tried it yet. Anyway my question is : How can I convert a
> floating point value to a 32-bit unsigned integer without qword stuff.

By subtracting 2^32 if the number is greater than or equal to 2^31.
This cannot handle the situation where your number is exactly 2^31
though, and it's also probably slower than using qword stuff. The
FPU only works with signed integers really.

--
----------------------------------------------------------------
Paul Schlyter, Swedish Amateur Astronomer's Society (SAAF)
Nybrogatan 75 A, S-114 40 Stockholm, SWEDEN
e-mail: pau...@saaf.se

Terje Mathisen

unread,
Oct 23, 1995, 3:00:00 AM10/23/95
to
jkee...@vnet.ibm.com wrote:
>In <5w52z...@qcont.ndh.com>, m.so...@qcont.ndh.com (Markus Solbach) writes:
>>I am new in floating point programming and encountered the following
>>problem.
>>When I try to convert a floating point number to an unsigned integer
>>using the 'fist' or 'fistp' instruction I get a fpu exception if the
>>number that has to be converted is greater than 2^31. This means that
>>the highest bit (sign bit) in the integer converted number must be set.
>>I guess the fpu generates an overflow exception. Am I right?
>>My solution to this problem is to store a qword instead of a dword but
>>I have not tried it yet. Anyway my question is : How can I convert a
>>floating point value to a 32-bit unsigned integer without qword stuff.

I was going to say that you cannot, but then this post appeared:


>
>Subtract 2^31 before storing the number out and add 2^31 after storing the
>number.

This is of course correct, but it will cost you at least 4-5 cycles/conversion, even
on a Pentium, making the slow FIST opcode even worse.

A much faster way is to trick the fpu to do the job for you, avoiding the FIST opcode
totally:

; Input: St(0) has number which should be moved to register REG as unsigned long
; Output: St(0) popped, REG has 32-bit integer portion; no overflow checking!

.data
magic_double dq 4330000000000000h ; 2^52 as a double number!

temp_ulong label dword
temp_double dq ?

fp2ulong MACRO REG
fadd [magic_double]
fstp [temp_double]
mov REG,[temp_ulong]
ENDM

Since FADD is a pipeline-able instruction, this version of the code can be executed
in just 4 effective cycles, assuming you can insert some other instructions (FP or
Int) between the FADD and the FSTP.

If you do it by the book, you must either use FISTP qword ptr [temp], or the pre- and
post-conversion suggested by jkeenley, which will use at least 5 cycles more,
assuming perfect scheduling.

--
-Terje Mathisen (include std disclaimer) <Terje.M...@hda.hydro.com>
"almost all programming can be viewed as an exercise in caching"

0 new messages