[Oberon] real to longint

Patrik Reali reali at acm.org
Thu Aug 14 00:20:40 CEST 2003

The language report defines ENTIER (x) as "the largest integer not greater
than x".

On IA32 (aka Intel) machines, the default behaviour of the FPU is "round to
nearest". For ENTIER, the FPU mode must be changed to "round to -infinity".
Because of the peculiar (also said brain dead) design of the IA32 FPU,
changing the rounding mode is quite complicated and expensive and requires
as many as 4-5 instructions.

It is somewhat strange, that the Oberon language provides only this function
(pascal also had TRUNC).

Jacques' routine is obviously faster but implements a slightly different
semantic (round to nearest). You may think that this is a tiny detail, but
changing this in the language breaks quite some code using reals (in
particular in the GUI and the printing support) [yes, we tried that!].


----- Original Message -----
From: "Jacques Eloff" <eloff at cs.sun.ac.za>
To: <oberon at inf.ethz.ch>
Sent: Thursday, August 14, 2003 2:56 AM
Subject: Re: [Oberon] real to longint

> Hi
> ENTIER works fine, but changes the rounding of the FPU. I'm talking
> Intel now (Patrik, please correct me if I'm wrong). From what I can
> when ENTIER is used, the compiler first pushes the FPU control word onto
> stack, changes it to 400H (Which selects 'round to negative infinity'),
> 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
> 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
> 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
> Regards
> --
> Jacques Eloff
> Department of Computer Science
> University of Stellenbosch
> http://www.cs.sun.ac.za/~eloff
> --
> Oberon at inf.ethz.ch mailing list for ETH Oberon and related systems
> http://www.lists.inf.ethz.ch/mailman/listinfo/oberon

More information about the Oberon mailing list