[Oberon] real to longint
eloff at cs.sun.ac.za
Thu Aug 14 02:56:05 CEST 2003
ENTIER works fine, but changes the rounding of the FPU. I'm talking strictly
Intel now (Patrik, please correct me if I'm wrong). From what I can gather,
when ENTIER is used, the compiler first pushes the FPU control word onto the
stack, changes it to 400H (Which selects 'round to negative infinity'), does
the FISTP (floating point integer store with pop) and then restores the
floating point control word. Try displaying 3.6.
Texts.WriteRealFix gives 3.599999.....
ENTIER(3.6) = 3
The routine below gives 4 since it uses the default rounding.
I suspect the 3 is because Oberon always rounds and ENTIER explicitly selects
Shortest way I can think is the following:
PROCEDURE -Real2Longint(r: REAL): LONGINT;
FLD DWORD [ESP] ; Load r into ST(0)
FISTP DWORD [ESP] ; Store ST(0) in [ESP] and pop ST(0)
POP EAX ; EAX = [ESP]
Since its an inline routine, there's 0 overhead, except for the real which is
pushed on to the CPU stack. It reuses the stack space allocated to r by
storing the LONGINT in its place and popping it back as the function result.
Department of Computer Science
University of Stellenbosch
More information about the Oberon