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
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 -
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
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 Beginners@lists.squeakfoundation.org http://lists.squeakfoundation.org/mailman/listinfo/beginners
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
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 Beginners@lists.squeakfoundation.org http://lists.squeakfoundation.org/mailman/listinfo/beginners
Beginners mailing list Beginners@lists.squeakfoundation.org http://lists.squeakfoundation.org/mailman/listinfo/beginners
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 Beginners@lists.squeakfoundation.org http://lists.squeakfoundation.org/mailman/listinfo/beginners
Beginners mailing list Beginners@lists.squeakfoundation.org http://lists.squeakfoundation.org/mailman/listinfo/beginners
Beginners mailing list Beginners@lists.squeakfoundation.org http://lists.squeakfoundation.org/mailman/listinfo/beginners
beginners@lists.squeakfoundation.org