accurate comparisons of int to float?
Jon L White
uunet!lucid.com!jonl
Tue Aug 14 09:38:54 PDT 1990
re: In traditional K&R C the program works as expected. Common Lisp, 1st
edition, had a similar bug in defining comparisons of integers to floating
point, but I've been told that the 2nd edition fixes this and requires
exact comparison.
The 2nd edition of CLtL ("Common Lisp: The Language") is describing the
state of the X3J13 proposal for an ANSI Common Lisp standard. In the case
of floating comparisons, the first edition defined a simple, uniform rule
about numerical "contagion" in mixed mode expressions; that rule required
the floating of any rational number before doing the comparison.
However, certain users of Lucid Common Lisp found that rule "broken",
as the following excerpts from the Lucid internal bug database shows.
Subsequent discussion on the public mailing list "Common-LispaMCC.COM"
(formerly "common-lispasail.stanford.edu") confirmed that the simple
rule of contagion violated a much deeper principle of expectation of
transitivity of these comparison operators. Accordingly, X3J13 voted
in January 1989 to opt for transitivity over simplicity of "contagion",
as the Lucid implementation had already done (see the issue called
CONTAGION-ON-NUMERICAL-COMPARISONS).
Excerpt from Lucid bug report #1282
ENTRY: jonl Reported Thu Nov 13 11:30:11 1986
MACHINE: Sun
Numeric equality is often wrong when a float is compared to a
rational; this is because it is coercing a rational to a float
rather a float to a rational. Since floatification is an information
losing process, there are many examples of rationals which are distinct,
but whose floated conversions are the same.
-- JonL and jeb --
Excerpt from Lucid bug report #1282
ENTRY: jonl Reported Fri Oct 16 01:07:42 1987
MACHINE: Sun
Date: Mon, 12 Oct 87 22:03:27 EST
From: Jon L White <jonl>
To: jeb, maj, hbs, fy
Cc: jonl
Subject: floating-point inequality functions: a "Sleeping Dog"?
. . . we need to resolve a point. How should one do the comparison
(<= fx i)
Where 'fx' is a floating-point number and 'i' is an integer? Currently,
we do the comparison by first floating 'i', and using the floating-point
comparison functions. But look at the following anomaly:
(setq i #x2000000)
(setq fx (float i))
Now
(<= fx (+ i 1)) ==> T
(< (+ i 1) (+ i 2)) ==> T
(<= (+ i 2) fx) ==> T
which is summarized by:
fx <= i+1 < i+2 <= fx
Or, put bluntly, fx < fx, an absurdity.
Shouldn't we upgrade the generic numeric inequality functions to use
contagion to rationals rather than contagion to floats?
Jeb and I already did this for numeric equality; see bug # 1282
(from "miami").
-- JonL --
One of the factors in convincing a broader acceptance of this more
complex rule was to note that a compiler writer could still do a good
deal of optimization that needn't require conversion of huge floats
(e.g., 3.705885643377958E300) to "bignum" format, or of moderate ones
(e.g., 3.705885643377958E10 = 15972367122959/431) to the slower "ratio"
format. For example, comparison of any quantity declared to be a float
with any other declared to be a fixnum can still proceed to float the
fixnum quantity and do ordinary floating comparison, since that conversion
is guaranteed not to be information-losing.
[Remarks: (1) Yes Common Lisp has always permitted a great deal of static
typing in the language, and implementaitons on "stock hardware" find this
to be a critical aspect of the usability of Lisp. (2) The desirability of
using floating point operations in some RISC machines is heightened by the
existence of floating-point co-processers on them; in fact, it is often
preferable to do fixed-point multiplication and division by first converting
the arguments to floating point, doing the operation in the co-processor,
and then converting back.]
-- JonL --
More information about the Numeric-interest
mailing list