From: Peter Seibel
Subject: EQL and floats
Date: 
Message-ID: <m3of2z3y8y.fsf@javamonkey.com>
In the CLHS dictionary entry for EQL it says:

  eql may not be true of two floats even when they represent the same
  value.

What does "the same value" mean in this context. For instance, is this
saying that (eql 1.0 1.0) may be either true or false? Or just
something like (eql (/ 6.0 2.0) 3.0)?

-Peter

-- 
Peter Seibel                                      ·····@javamonkey.com

  The intellectual level needed   for  system design is  in  general
  grossly  underestimated. I am  convinced  more than ever that this
  type of work is very difficult and that every effort to do it with
  other than the best people is doomed to either failure or moderate
  success at enormous expense. --Edsger Dijkstra

From: Lars Brinkhoff
Subject: Re: EQL and floats
Date: 
Message-ID: <857k9nkq10.fsf@junk.nocrew.org>
Peter Seibel <·····@javamonkey.com> writes:
> In the CLHS dictionary entry for EQL it says:
>   eql may not be true of two floats even when they represent the same
>   value.
> What does "the same value" mean in this context.

From
  http://www.lisp.org/HyperSpec/Body/fun_eql.html
I take it to mean that two differently typed floats representing
the same number doesn't compare equal under eql.

> For instance, is this saying that (eql 1.0 1.0) may be either true
> or false?

Always true, I believe.  (eql 1.0s0 1.0d0) should be true iff
(eq (type-of 1.0s0) (type-of 1.0d0)).
From: Scott McKay
Subject: Re: EQL and floats
Date: 
Message-ID: <0Papa.42738$gK.149047@rwcrnsc52.ops.asp.att.net>
"Peter Seibel" <·····@javamonkey.com> wrote in message
···················@javamonkey.com...
> In the CLHS dictionary entry for EQL it says:
>
>   eql may not be true of two floats even when they represent the same
>   value.
>
> What does "the same value" mean in this context. For instance, is this
> saying that (eql 1.0 1.0) may be either true or false? Or just
> something like (eql (/ 6.0 2.0) 3.0)?
>

Here's the deal.  'eql' returns true iff
 - the two objects are 'eq'
 - or two characters are "the same"
 - or two numbers have the same type and same value

Note that two floating point numbers can be numerically equal
without having the same type!  (eql 1.0d0 1.0s0) should evaluate
to false on Lisps that support double precision.

Expressions like (eql (/ 6.0 2.0) 3.0) evaluate to false if the floating
point precision of the reader and of the arithmetic operators are
not quite "the same".  I'm too lazy to type all the details of this, tho'.
From: Gisle Sælensminde
Subject: Re: EQL and floats
Date: 
Message-ID: <slrnbaajri.q36.gisle@kaktus.ii.uib.no>
In article <··············@javamonkey.com>, Peter Seibel wrote:
> In the CLHS dictionary entry for EQL it says:
> 
>   eql may not be true of two floats even when they represent the same
>   value.
> 
> What does "the same value" mean in this context. For instance, is this
> saying that (eql 1.0 1.0) may be either true or false? Or just
> something like (eql (/ 6.0 2.0) 3.0)?
> 
> -Peter
> 

It is almost always wrong to compare two floating point numbers
for equality. Your example just happens to work because you divide
by two, unlike the following example:

(eql (- (- 5.11 5.0) 0.11) 0.0)
NIL

This is off cause becuase the floating point unit gives round-off 
errors, so (- (- 5.11 5.0) 0.11) don't give exactly 0, 

(- (- 5.11 5.0) 0.11)
1.3411045e-7

Equality with floating point numbers should be handled with caution. 
This comes in addition to the type issues mentioned by others. 
It is difficult to get the same value on both side in floating point
calculations. 

--
Gisle S�lensminde  
Computational biology unit, University of Bergen, Norway
Email: ·····@cbu.uib.no 
Biology easily has 500 years of exciting problems to work on. (Donald Knuth)
From: Joe Marshall
Subject: Re: EQL and floats
Date: 
Message-ID: <adei5u9t.fsf@ccs.neu.edu>
Gisle S�lensminde <·····@kaktus.ii.uib.no> writes:

> It is almost always wrong to compare two floating point numbers
> for equality. Your example just happens to work because you divide
> by two, unlike the following example:
> 
> (eql (- (- 5.11 5.0) 0.11) 0.0)
> NIL
> 
> This is off cause becuase the floating point unit gives round-off 
> errors, so (- (- 5.11 5.0) 0.11) don't give exactly 0, 
> 
> (- (- 5.11 5.0) 0.11)
> 1.3411045e-7

While your example works, there is no floating point round-off error
during the computation.  (The error occurs during the READ of the
numbers.)  I'm being pedantic, but it's worth understanding.

5.0 is represented, in floating point, as the rational number
10485760/2097152 (exactly equal to 5)

5.11 is represented as
10716447/2097152 (a tad more that 511/100)

subtracting gives exactly
230687/2097152 which is normalized to the exact equivalent
14763968/134217728

so there is no rounding error in this subtraction

.11 is represented as
14763950/134217728 (a tad less than 11/100)

subtracting again gives exactly
18/134217728 which is normalized to 
9437184/70368744177664 
which is printed as  1.3411045e-7

so there is no rounding error in the second subtraction, either.

All the error occurs at read time when the decimal value is converted
to a float.
  
From: Peter Seibel
Subject: Re: EQL and floats
Date: 
Message-ID: <m3fzoa4if8.fsf@javamonkey.com>
Gisle S�lensminde <·····@kaktus.ii.uib.no> writes:

> In article <··············@javamonkey.com>, Peter Seibel wrote:
> > In the CLHS dictionary entry for EQL it says:
> > 
> >   eql may not be true of two floats even when they represent the
> >   same value.
> > 
> > What does "the same value" mean in this context. For instance, is this
> > saying that (eql 1.0 1.0) may be either true or false? Or just
> > something like (eql (/ 6.0 2.0) 3.0)?
> > 
> > -Peter
> > 
> 
> It is almost always wrong to compare two floating point numbers
> for equality. Your example just happens to work because you divide
> by two, unlike the following example:
> 
> (eql (- (- 5.11 5.0) 0.11) 0.0)
> NIL
> 
> This is off cause becuase the floating point unit gives round-off 
> errors, so (- (- 5.11 5.0) 0.11) don't give exactly 0, 
> 
> (- (- 5.11 5.0) 0.11)
> 1.3411045e-7
>
> Equality with floating point numbers should be handled with caution.
> This comes in addition to the type issues mentioned by others. It is
> difficult to get the same value on both side in floating point
> calculations.

Right. I get that. But I wouldn't call 0.0 and 1.3411045e-7 the "same"
value. So I was wondering what it meant for the values to be the
"same" yet not EQL. The case of (eql 1.0s0 1.0d0) ==> false makes
sense; I hadn't thought of that possibility.

-Peter


-- 
Peter Seibel                                      ·····@javamonkey.com

  The intellectual level needed   for  system design is  in  general
  grossly  underestimated. I am  convinced  more than ever that this
  type of work is very difficult and that every effort to do it with
  other than the best people is doomed to either failure or moderate
  success at enormous expense. --Edsger Dijkstra
From: Gisle Sælensminde
Subject: Re: EQL and floats
Date: 
Message-ID: <slrnbabgd9.o39.gisle@apal.ii.uib.no>
In article <··············@javamonkey.com>, Peter Seibel wrote:
> Gisle S�lensminde <·····@kaktus.ii.uib.no> writes:
> 
> 
> Right. I get that. But I wouldn't call 0.0 and 1.3411045e-7 the "same"
> value. So I was wondering what it meant for the values to be the
> "same" yet not EQL. The case of (eql 1.0s0 1.0d0) ==> false makes
> sense; I hadn't thought of that possibility.

My point was that floating points almost never is the "same" after
a computation, and I guess we agree there, but I just corrected a 
colleague's code that was broken exactly for the reason that he used
equality for checking that the results of a computation were the same.

As Joe Marshall pointed out, my example was not an example of
rounding errors, but that floating point numbers don't always represent 
the input value exactly. 

Floating point are not easy.... 


-- 
--
Gisle S�lensminde  
Computational biology unit, University of Bergen, Norway
Email: ·····@cbu.uib.no 
Biology easily has 500 years of exciting problems to work on. (Donald Knuth)
From: Peter Seibel
Subject: Re: EQL and floats
Date: 
Message-ID: <m34r4q2ijd.fsf@javamonkey.com>
Gisle S�lensminde <·····@apal.ii.uib.no> writes:

> In article <··············@javamonkey.com>, Peter Seibel wrote:
> > Gisle S�lensminde <·····@kaktus.ii.uib.no> writes:
> > 
> > 
> > Right. I get that. But I wouldn't call 0.0 and 1.3411045e-7 the "same"
> > value. So I was wondering what it meant for the values to be the
> > "same" yet not EQL. The case of (eql 1.0s0 1.0d0) ==> false makes
> > sense; I hadn't thought of that possibility.
> 
> My point was that floating points almost never is the "same" after a
> computation, and I guess we agree there, but I just corrected a
> colleague's code that was broken exactly for the reason that he used
> equality for checking that the results of a computation were the
> same.
> 
> As Joe Marshall pointed out, my example was not an example of
> rounding errors, but that floating point numbers don't always
> represent the input value exactly.
> 
> Floating point are not easy.... 

No. They are deep voodoo as far as I'm concerned. Beyond the type
difference problem, an email correspondent pointed out that you can
also have normalization differences: The same value can be represented
as 1 x 2^1 and 2 x 2^0. But the bit-patterns would be different and
EQL isn't obligated to figure out that they are the same value.

Or something. As I said, it's all voodoo to me.

-Peter

-- 
Peter Seibel                                      ·····@javamonkey.com

  The intellectual level needed   for  system design is  in  general
  grossly  underestimated. I am  convinced  more than ever that this
  type of work is very difficult and that every effort to do it with
  other than the best people is doomed to either failure or moderate
  success at enormous expense. --Edsger Dijkstra
From: Raymond Toy
Subject: Re: EQL and floats
Date: 
Message-ID: <4n7k9ls1cp.fsf@edgedsp4.rtp.ericsson.se>
>>>>> "Peter" == Peter Seibel <·····@javamonkey.com> writes:

    Peter> No. They are deep voodoo as far as I'm concerned. Beyond the type
    Peter> difference problem, an email correspondent pointed out that you can
    Peter> also have normalization differences: The same value can be represented
    Peter> as 1 x 2^1 and 2 x 2^0. But the bit-patterns would be different and
    Peter> EQL isn't obligated to figure out that they are the same value.

Yes, there is a normalization issue, but just about everyone
implements IEEE floating-point arithmetic so all numbers are always
normalized if they are within range.  So it's not possible to get 1 x
2^1 and 2 x 2^0.  It's always 1 x 2^1.

Ray
From: Joe Marshall
Subject: Re: EQL and floats
Date: 
Message-ID: <of2xnria.fsf@ccs.neu.edu>
> Gisle S�lensminde <·····@apal.ii.uib.no> writes:
> > Floating point are not easy.... 

Peter Seibel <·····@javamonkey.com> writes:
> No. They are deep voodoo as far as I'm concerned. 

They really aren't all that bad.  Read a few of the papers on William
Kahan's web site:  http://www.cs.berkeley.edu/~wkahan/

The thing to realize is this:  floating point numbers are exact
rational numbers.  In particular, they are a selected set of exact
rational numbers.  In any binary float, the denominator is a power of
2.  In single precision, the numerator is an integer between 8388608
and 16777215.  In double precision, the numerator is and integer
between 4503599627370496 and 9007199254740991.  All the usual rules of
rational arithmetic apply to floating point numbers, except for one:
if the result is not expressible in the floating point format, the
result is rounded to the nearest number that *is* expressible.  (And
good floating point hardware has a means to let you know if it needed
to round or not.)