Richard Fateman <fateman at eecs.berkeley.edu> writes:
> On 12/17/2012 3:52 PM, Stavros Macrakis wrote:
>
> I'd say that floats represent imprecise or approximate?numbers, so
> 3.0 might mean exactly 3 or some other number in the interval
> 3-eps .. 3+eps.
[...]
> ?I suspect that "professional"
> numerical analysts would, by and large, say that floats represent
> exactly some particular number. That is,
> 3.0 represents exactly the quantity 3.
I certainly agree that 3.0 should not be considered an interval. In
addition to the points raised by Richard, I'll add that the interval
3-eps .. 3+eps does not contain the true result of all computations
that produce 3.0. In fact, no finite interval can do so.
At the same time, I agree with Stavros' assertion that floats should be
considered "imprecise or approximate numbers". I think it's possible to
adopt this position while simultaneously agreeing with numerical
analysts that 3.0 represents a single quantity that is equal to 3.
Scheme's number system includes some innovations that are helpful to
resolve tensions such as this. Notably, Scheme introduced the concept
of "exactness", and the type predicates such as 'real?', 'rational?' and
'integer?' are closer to their mathematical definitions than in CL and
do not merely reflect the internal representation used.
In Scheme, 3.0 is an integer (i.e. 'integer?' returns true and it is
accepted by integer operations such as 'gcd'), but unlike 3 it is not
an /exact/ integer (i.e. 'exact?' returns false). Similarly, 3.5 is
'rational?' but unlike 7/2 it is not an /exact/ rational.
Note that here "exact" is being used in a different sense than Richard
Fateman used above. Indeed, 3.0 does not represent an interval but
rather a single number that is equal to 3.
Quoting section 6.2.2 of the (pleasantly concise) R5RS Scheme standard:
Scheme numbers are either exact or inexact. A number is exact if it
was written as an exact constant or was derived from exact numbers
using only exact operations. A number is inexact if it was written as
an inexact constant, if it was derived using inexact ingredients, or
if it was derived using inexact operations. Thus inexactness is a
contagious property of a number.
If two implementations produce exact results for a computation that
did not involve inexact intermediate results, the two ultimate results
will be mathematically equivalent. This is generally not true of
computations involving inexact numbers since approximate methods such
as floating point arithmetic may be used, but it is the duty of each
implementation to make the result as close as practical to the
mathematically ideal result.
Rational operations such as '+' should always produce exact results
when given exact arguments. If the operation is unable to produce an
exact result, then it may either report the violation of an
implementation restriction or it may silently coerce its result to an
inexact value.
In typical Scheme implementations, exactness is determined by the
underlying representation used to store the number: for real numbers,
flonums are inexact, and fixnums, bignums, and ratnums are exact.
Complex numbers are exact if and only if both components are exact.
Exactness can be tested using the predicates 'exact?' and 'inexact?'.
Note that inexact integers such as 3.0 are accepted by integer
arithmetic operators (e.g. 'gcd' and 'modulo'), but they are _not_
accepted as indices into data structures (e.g. by 'vector-ref').
The idea is to allow the construction of robust programs that are
not vulnerable to round-off errors.
I wonder if it might be desirable to somehow adapt some of these ideas
into Maxima.
Regards,
Mark