From: Vladimir Zolotykh
Subject: Float numbers equivalence question
Date: 
Message-ID: <3D22D751.EDE8025F@eurocom.od.ua>
Suppose I have a function

(defun test-p (a b)
  (declare (single-float a b))
  (declare (optimize (speed 3) (safety 1) (space 0) (debug 0)))
  (equal a b))

Is it true to say that ultimately during execution of 
TEST-P the some floating-point processor (FPU) instruction (or
emulation of such) will be issued. Based on its result
TEST-P returns its own result.

For example I see

(test-p 0.33333334 0.33333334) => t
(test-p 0.33333334 0.33333332) => nil

Does this mean that CL equivalence of floats is the same
as FPU has ?

Is this equally applicable to other comparisons on float
numbers ?

- 
Vladimir Zolotykh

From: Barry Margolin
Subject: Re: Float numbers equivalence question
Date: 
Message-ID: <ZkEU8.8$354.246@paloalto-snr1.gtei.net>
In article <·················@eurocom.od.ua>,
Vladimir Zolotykh  <······@eurocom.od.ua> wrote:
>Suppose I have a function
>
>(defun test-p (a b)
>  (declare (single-float a b))
>  (declare (optimize (speed 3) (safety 1) (space 0) (debug 0)))
>  (equal a b))
>
>Is it true to say that ultimately during execution of 
>TEST-P the some floating-point processor (FPU) instruction (or
>emulation of such) will be issued. Based on its result
>TEST-P returns its own result.

That's a likely possibility.  Or it might just do a direct comparison of
the two bit patterns.  But if it supports IEEE NaN's, it would have to
special-case them, becase (= NaN NaN) => nil; the FPU probably already does
automatically.

>For example I see
>
>(test-p 0.33333334 0.33333334) => t
>(test-p 0.33333334 0.33333332) => nil
>
>Does this mean that CL equivalence of floats is the same
>as FPU has ?

I don't see that it proves anything about how it's done.  If you want to
know what instructions your implementation uses, (disassemble 'test-p).

>Is this equally applicable to other comparisons on float
>numbers ?

Less-than and greater-than must be done using floating point calculations.

-- 
Barry Margolin, ······@genuity.net
Genuity, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Raymond Toy
Subject: Re: Float numbers equivalence question
Date: 
Message-ID: <4nadp245z0.fsf@rtp.ericsson.se>
>>>>> "Barry" == Barry Margolin <······@genuity.net> writes:

    Barry> In article <·················@eurocom.od.ua>,
    Barry> Vladimir Zolotykh  <······@eurocom.od.ua> wrote:
    >> Is this equally applicable to other comparisons on float
    >> numbers ?

    Barry> Less-than and greater-than must be done using floating point calculations.

I think with IEEE FP numbers, comparison can be done by treating the
bits as integers.  But it makes sense to use the FPU since the numbers
are probably already there.

Ray
From: Joel Ray Holveck
Subject: Re: Float numbers equivalence question
Date: 
Message-ID: <y7cfzyrrv1i.fsf@sindri.juniper.net>
> I think with IEEE FP numbers, comparison can be done by treating the
> bits as integers.

I believe that for IEEE FP, then comparison on invalid bit patterns or
NaNs is supposed to trap.

Cheers,
joelh
From: Tim Olson
Subject: Re: Float numbers equivalence question
Date: 
Message-ID: <04lzvud73001-4550A5.21513610072002@reader.news.algx.net>
In article <··············@rtp.ericsson.se>,
 Raymond Toy <···@rtp.ericsson.se> wrote:

| >>>>> "Barry" == Barry Margolin <······@genuity.net> writes:
| 
|     Barry> Less-than and greater-than must be done using floating point 
|     calculations.
| 
| I think with IEEE FP numbers, comparison can be done by treating the
| bits as integers.

The integer comparison trick works when both float numbers aren't 
negative.  Since IEEE-754 format is sign-magnitude, integer comparison 
of two negative float values gets the comparison reversed.

-- 

     -- Tim Olson
From: Joel Ray Holveck
Subject: Re: Float numbers equivalence question
Date: 
Message-ID: <y7c4rfgckeu.fsf@sindri.juniper.net>
> (defun test-p (a b)
>   (declare (single-float a b))
>   (declare (optimize (speed 3) (safety 1) (space 0) (debug 0)))
>   (equal a b))
> Is it true to say that ultimately during execution of 
> TEST-P the some floating-point processor (FPU) instruction (or
> emulation of such) will be issued. Based on its result
> TEST-P returns its own result.

It's not necessarily true, no.  In fact, it may be not at all true.

Note that EQUAL for numbers behaves the same as EQL.  So it may use a
register compare (bit patterns) instead of a floating point compare,
depending on your Lisp implementation's representation of floats.

For example, with the Intel's FPU, FCOM tests for NaNs, validates the
number, and ignores the difference between -0.0 and +0.0.  But that
isn't what EQUAL necessarily does.  CMUCL reports:

  (equal -0.0 +0.0)
  => NIL

If you want to compare numeric values, use =, not EQUAL.  This will
usually (although not necessarily) use your FPU's comparison
instruction.

However, it's frequently a bad idea to use equality predicates with
floats in *any* language.  You can get some pretty nutty results that
way.  Generally, you'll want to use something like this in a lot of
cases:

(defparameter *epsilon* 0.0001)
(defun close-enough (a b)
  (< (abs (- a b)) *epsilon*))

> For example I see
> (test-p 0.33333334 0.33333334) =>t
> (test-p 0.33333334 0.33333332) =>nil
> Does this mean that CL equivalence of floats is the same
> as FPU has ?

I don't follow.  This doesn't indicate that the FPU even was involved
at all.

> Is this equally applicable to other comparisons on float
> numbers ?

Comparisons on floats are handled as if they were first made into
rationals, then compared.  This is to preserve transitivity in
comparisons; see CLtL2, sec 12.1.  This rule must be followed in all
ANSI CLs, so 

Cheers,
joelh