# floor & inexact->exact

Date: Fri, 3 Nov 89 09:31:26 -0500
From: Robert Hieb <hieb@iuvax.cs.indiana.edu>

Date: Thu Nov  2 20:52:46 1989
From: Alan Bawden <bawden@parc.xerox.com>
...If you -expected- an inexact quotient, then you probably should
have written (INEXACT->EXACT (FLOOR (/ P Q))).

Probably not.  I don't see how one can be sure that inexact->exact will
return an integer.  To be sure one must write
(floor (inexact->exact (/ p q))).

Recall that I was postulating a Scheme implementation without exact
rationals, only exact integers.  (INEXACT->EXACT (/ 5 3)) could plausibly
return and exact 1 or an exact 2 in such an implementation, or it might
signal an error, but it -can't- return an exact 5/3.  Thus

(FLOOR (INEXACT->EXACT (/ 5 3)))

might return (in that implementation) either an exact 1 or an exact 2 or it
might signal an error.  The latter two outcomes are probably not what was
expected.

So, if you -knew- that INEXACT->EXACT always rounded down in that Scheme
implementation, then you could indeed write (FLOOR (INEXACT->EXACT (/ P Q))).
(But note that this won't help you if you want to compute (ROUND (/ P Q)).)

If, on the other hand, you knew that the Scheme implementation in question
used floating point for its inexact numbers, then:

(/ 5 3)				=>  1.6666666
(FLOOR (/ 5 3))			=>  1.0
(INEXACT->EXACT (FLOOR (/ 5 3)))	=>  1

This works because floating point happens to have a representation for
-every- integer that might result from calling FLOOR, CEILING, TRUNCATE or
ROUND on another floating point number.

Now it seems to -me- to be more likely that you are porting your program to
a Scheme that uses floating point than to a Scheme who's INEXACT->EXACT is
guaranteed to always round down.  So -I- would write
(INEXACT->EXACT (FLOOR (/ P Q))).  If -you- want to bet the other way, that
is your choice.  (Note that I originally said you only that you "-probably-
should have written ...".)

In fact, -neither- order is guaranteed to work in -all- Scheme
implementations because there aren't enough constraints on the behavior of
inexact numbers.  INEXACT->EXACT is just like `<' in that you can't
usefully apply it to inexact arguments unless you know something more about
the inexact numbers you are using than is specified in the report.