Float comparsion

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Float comparsion

Camillo Bruni-2
Hy all,
I recently tried to compare two Float which apparently should be  
(nearly) the same.
I have to following excerpt:

        a := (Float halfPi / 2) tan
        a = 1.0

The comparison evaluates to false, although it should be 1.0.
How do I compare Floats so I get useful results?

I'm using Squeak 3.8.18beta3U VM and the
Squeak3.10.2-7179-basic.image on Mac OS X 10.5 with an Intel Core 2 Duo.

Thanks,
        Camillo
_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: Float comparsion

Bert Freudenberg

On 27.02.2009, at 13:22, Camillo Bruni wrote:

> Hy all,
> I recently tried to compare two Float which apparently should be  
> (nearly) the same.
> I have to following excerpt:
>
> a := (Float halfPi / 2) tan
> a = 1.0
>
> The comparison evaluates to false, although it should be 1.0.
> How do I compare Floats so I get useful results?
>
> I'm using Squeak 3.8.18beta3U VM and the
> Squeak3.10.2-7179-basic.image on Mac OS X 10.5 with an Intel Core 2  
> Duo.


Don't they teach you anything in Bern? ;-)

Floats are approximations. You can't meaningfully compare them for  
equality. One way is to use

        (a - b) abs < epsilon

- Bert -


_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: Float comparsion

Lukas Renggli
In reply to this post by Camillo Bruni-2
Hi Camillo ;-)

Use the method #closeTo: instead of #=. Comparing floats with #=
almost never works.

Although "(Float halfPi / 2) tan" is printed as 1.0, it is not exactly
1.0 due to rounding errors in the calucaltaion and/or the internal
representation.

    (Float halfPi / 2) tan - 1.0 --> -1.110223024625156e-16

Lukas

--
Lukas Renggli
http://www.lukas-renggli.ch
_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: Float comparsion

onierstrasz

Yes, we looked at that, but closeTo: uses a much larger epsilon than  
Float's class variable Epsilon.

I suggested Camillo wrote an extension method similar to closeTo: but  
using the existing Epsilon (or an arbitrary one as an additional  
parameter).

Is that the right thing to do?

- on

On Feb 27, 2009, at 13:34, Lukas Renggli wrote:

> Hi Camillo ;-)
>
> Use the method #closeTo: instead of #=. Comparing floats with #=
> almost never works.
>
> Although "(Float halfPi / 2) tan" is printed as 1.0, it is not exactly
> 1.0 due to rounding errors in the calucaltaion and/or the internal
> representation.
>
>    (Float halfPi / 2) tan - 1.0 --> -1.110223024625156e-16
>
> Lukas
>
> --
> Lukas Renggli
> http://www.lukas-renggli.ch
> _______________________________________________
> Beginners mailing list
> [hidden email]
> http://lists.squeakfoundation.org/mailman/listinfo/beginners

_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: Float comparsion

Lukas Renggli
> Yes, we looked at that, but closeTo: uses a much larger epsilon than Float's
> class variable Epsilon.

Yeah, that implementation is a bit strange ;-)

As far as I understand the method uses an epsilon value relative to
the bigger absolute value of the two numbers. Depending on the exact
behavior you want, you might need to write your own extension method
indeed.

    Number>>closeTo: aNumber epsilon: anEpsilon
         ^ self between: aNumber - anEpsilon and: aNumber + anEpsilon

Lukas

--
Lukas Renggli
http://www.lukas-renggli.ch
_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: Float comparsion

Bert Freudenberg
In reply to this post by onierstrasz
The Epsilon class variable is used only when the primitives for some  
float functions are not available, in which case they are approximated  
to that precision. Using that same epsilon for something else is as  
meaningless as the 0.0001 in #closeTo:.

The epsilon really depends on your application.

- Bert -

On 27.02.2009, at 13:41, Oscar Nierstrasz wrote:

>
> Yes, we looked at that, but closeTo: uses a much larger epsilon than  
> Float's class variable Epsilon.
>
> I suggested Camillo wrote an extension method similar to closeTo:  
> but using the existing Epsilon (or an arbitrary one as an additional  
> parameter).
>
> Is that the right thing to do?
>
> - on
>
> On Feb 27, 2009, at 13:34, Lukas Renggli wrote:
>
>> Hi Camillo ;-)
>>
>> Use the method #closeTo: instead of #=. Comparing floats with #=
>> almost never works.
>>
>> Although "(Float halfPi / 2) tan" is printed as 1.0, it is not  
>> exactly
>> 1.0 due to rounding errors in the calucaltaion and/or the internal
>> representation.
>>
>>   (Float halfPi / 2) tan - 1.0 --> -1.110223024625156e-16
>>
>> Lukas
>>
>> --
>> Lukas Renggli
>> http://www.lukas-renggli.ch
>> _______________________________________________
>> Beginners mailing list
>> [hidden email]
>> http://lists.squeakfoundation.org/mailman/listinfo/beginners
>
> _______________________________________________
> Beginners mailing list
> [hidden email]
> http://lists.squeakfoundation.org/mailman/listinfo/beginners



_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: Float comparsion

Camillo Bruni-2
hehe thanks for the vivid response ;)
Well then I'll use closeTo, I don't really need a very accurate comparison.
But since I want to create a Renderer the performance will be the biggest
problem. Well thats also why I've chosen Squeak ;).


thanks for the responses


Am 27.02.2009 um 13:51 schrieb Bert Freudenberg:

The Epsilon class variable is used only when the primitives for some float functions are not available, in which case they are approximated to that precision. Using that same epsilon for something else is as meaningless as the 0.0001 in #closeTo:.

The epsilon really depends on your application.

- Bert -

On 27.02.2009, at 13:41, Oscar Nierstrasz wrote:


Yes, we looked at that, but closeTo: uses a much larger epsilon than Float's class variable Epsilon.

I suggested Camillo wrote an extension method similar to closeTo: but using the existing Epsilon (or an arbitrary one as an additional parameter).

Is that the right thing to do?

- on

On Feb 27, 2009, at 13:34, Lukas Renggli wrote:

Hi Camillo ;-)

Use the method #closeTo: instead of #=. Comparing floats with #=
almost never works.

Although "(Float halfPi / 2) tan" is printed as 1.0, it is not exactly
1.0 due to rounding errors in the calucaltaion and/or the internal
representation.

 (Float halfPi / 2) tan - 1.0 --> -1.110223024625156e-16

Lukas

--
Lukas Renggli
http://www.lukas-renggli.ch
_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners

_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners



_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners


_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners