[Oberon] real to longint

Jacques Eloff eloff at cs.sun.ac.za
Thu Aug 14 02:56:05 CEST 2003


Hi

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 
this option

Shortest way I can think is the following:

PROCEDURE -Real2Longint(r: REAL): LONGINT;
CODE {SYSTEM.i386}
  FLD DWORD [ESP]      ; Load r into ST(0)
  FISTP DWORD [ESP]   ; Store ST(0) in [ESP] and pop ST(0)
  POP EAX                     ; EAX = [ESP]
END Real2Longint;

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. 

Regards


-- 
Jacques Eloff
Department of Computer Science
University of Stellenbosch
http://www.cs.sun.ac.za/~eloff




More information about the Oberon mailing list