# Numbers and Pork Rinds

```    Date: Fri, 25 Aug 89 10:30:39 PDT
From: harrison@s45.csrd.uiuc.edu (Luddy Harrison)
...  I have but a minor comment to make.  Alan, the inexactness you
attribute to floating point numbers is not a property of the
representation itself, but rather its interpretation (as a projection
of the space of real values).

No, I don't myself "attribute" inexactness to floating point numbers at
all.  In the context of the current discussion, the notion of an "inexact"
number has a purely technical meaning.  An inexact number is a Scheme
object that the predicate INEXACT? is true of.  It just so happens that the
most common technique for implementing inexact numbers is to use a floating
point representation (and not to use floating point for anything else), and
so in most Scheme implementations the two notions coincide.

This need not be the case.

Floating point numbers can be used as a representation for exact (rational)
numbers as well, if an implementation chooses.  But since the set of
rationals represented exactly by floating point is not even approximately
closed under even the most common operations (consider (/ 1 3) or
(+ 1 1000000000000000000000000000000)), this doesn't seem to be a viable
choice.

Better is to play the game the other way, and use representations usually
used for exact numbers to represent inexact numbers.  For example, A
convincing case can be made for using ratios to do inexact arithmetic.
(See the paper by Berthold Horn that describes this [an MIT AI Memo, I
think, I don't have my copy here].)

I, knowing the algebra of a floating
point implementation, may certainly write down an "exact" computation
in terms of floating point values.  For example: (+ 2.0 3.0).  Knowing
that by 2.0 and 3.0 I mean exactly 2 and 3, and knowing
the floating point unit of my machine, I know that the 5.0 that
results will be an "exact" result.

By the same token, I may write down an "inexact" computation in
terms of integers.  For example, let H be a procedure that
heuristically evaluates a chess position and returns an integer
representing the goodness of the position.  I interpret H's return
value as an interval, a distribution, around the "real" goodness of
the board.  Now, when I write (max (H board-1) (H board-2)), I don't
expect max to understand that its arguments are grossly lacking in
precision.  Neither would I expect it to do so if H returned a
floating point value.

This is all true, but doesn't address the issue of what happens if you
actually write a Scheme program to perform the computations you describe, and
then apply the predicates EXACT? and INEXACT? to the various Scheme objects
being manipulated.  The "inexact" measure of the goodness of a particular
chess position may well be represented by a Scheme number that EXACT? is
true of.  If you try and make the two notions of "exactness" coincide -- so
that INEXACT? will be true of all numbers that you know have a heuristic
derivation -- then most Scheme implementations will force you to be working
with floating point numbers.

It is my job to determine the MEANING of the
representations I ask the computer to manipulate; I want only for the
computer to act predicatably upon the representations.  Predictably,
in the case of floating point values, has traditionally meant that the
computer behaves as though the values were exact.

On the machine I am using right now:

(/ 1.0 3.0)  ==>  0.3333333432674407958984375

I suppose there is some sense in which this is "behaving as though the
values were exact".  The value returned is in fact a -particular- rational
number.  (It normally prints as "0.33333334" -- I have shown it here
printed precisely.)  But it is not the -same- rational number that would be
returned in a different Scheme implementation, and it is not the same
rational number that a mathematician would compute with pencil and paper.

The sense of "inexact" that Scheme implements with its INEXACT? and EXACT?
predicates is that an exact number is an object that represents a
particular number, and that number was computed in such a way that the
implementation is certain that the -same- particular number would be
computed in any other implementation.  The user can allow this condition to
become violated if he uses the procedure INEXACT->EXACT or any of the
numeric predicates.  The current debate is about whether MAX and MIN also
allow this condition to become violated.

```