2009/7/8 danil osipchuk <[email protected]>:
>>>
>>> I repeat here my arguments:
>>> Anyone depending on (13/10) = 1.3 is plain wrong...
>>>
>> +1.
>> I dealt with 3D rendering/linear algebra using floats in the past ,
>> and i can say just one:
>> - never write the code which compares the floats to be equal to some
>> exact value.
>> It makes no sense in practice, because of inexact nature of floats.
>
> +1 me too
> Code like '(13/10) = 1.3' just jumps at you if you have been bitten by
> this before.
> In languages of APL branch (which are traditionally used for
> intensive calculations) the comparison of real numbers is 'tolerant':
> that is two numbers are considered equal if their relative difference
> is less than some predefined small value:
> a = b isTrue if: |a-b|/max(a,b) < Epsilon
>
Sorry, I can't help talking :)
Of course, this model does not preserve good properties like = being transitive.
a := 1.0 - (0.5*Epsilon).
b := 1.0.
c := 1.0 + (0.5*Epsilon).
self assert: (a = b) & (b = c) ==> (a = c).
So I'd rather stick to a keyword selector like fuzzyEqual:
Again, this definition corresponds more to an Interval arithmetic model.
RealInterval >> fuzzyEqual: b
^(self intersectionWith: b) notEmpty
Smalltalk has both exact (Integer/Fraction/ScaledDecimals) and inexact
(Float) arithmetic, and the semantic of = will vary from exactEqual:
to fuzzyEqual:.
RealInterval >> exactEqual: b
"always false, if a or b are inexact"
^a isExact and: [b isExact and: [a bounds exactEqual: b bounds]]
RealInterval >> isExact
"self is exact if Card(self) = 1"
^a bounds min exactEqual: a bounds max
Don't confuse with = that could simply mean that they represent the
same interval
RealInterval >> = b
^a bounds exactEqual: b bounds
I did not care much of polymorphism (coercion, double dispatching or
whatever), but you get the idea.
You can also use probability distributions if it better fits your
model, but mathematical background might be a bit short...
Nicolas
> http://www.jsoftware.com/help/primer/tolerance.htm
> http://jsoftware.com/help/dictionary/d000.htm
>
> Creators of these languages put a lot of considiration into this and
> it I think they got it right.
> It may be too radical to redefine comparison of real values in
> Smalltalk (although it still makes sense to do so in practical terms)
> but the discussed test is just a blind shot into a sky. The user
> should be discouraged to rely on a such comparison.
>
> regards,
> Danil
>
>> As we know, if two vectors is perpendicular, then their dot product is zero.
>> But it is almost always non-zero on hardware, especially when you
>> transform vectors or compute them using data, which already contains a
>> degree of precision error!
>> So, i learned that comparing dot product with zero makes no sense,
>> instead you'd better test it with something like:
>>
>> abs(float) < epsilon
>> where epsilon is very small number.
>>
>> So, i don't understand, why its so important for such kind of equality
>> tests to work right at all - because you hardly will use such tests in
>> practice.
>>
>>> Either you want fast and inexact floating point operation and should
>>> not rely on exact equality (use #closeTo:).
>>> Or you want (13/10) = 1.3 EXACTLY, and then should better use ScaledDecimal.
>>> That's the deal, and it's quite independant from the language.
>>>
>>> The false assertions that people are trying to push does not matter:
>>> it's high time to educate.
>>> My proposition has at least the merit to put a light on these
>>> dangerous floating point strict equality tests
>>> (I saw so many bugs like testing cos(pi/2) == 0).
>>>
>>> And I'm still waiting for the hypothetical application that would
>>> break because of this change.
>>> That's the main point of interest.
>>> In this case, we'll see if patching is necessary and easy.
>>>
>>> Nicolas
>>>
>>> P.S. concerning behaviour of conversion binary<->decimal
>>> representation, I'm rather the one trying to unify Smalltalk.
>>> Dolphin, gst and Pharo adopted some of my changes to behave as exactly
>>> as we can, and thus behave the same.
>>> Try this in your prefered dialect, I guess you will have some surprise.
>>> 123.4567890123d3 = (1234567890123/10000000).
>>> 123.4567890123d3 = (1234567890123/10000000) asFloat.
>>>
>>> _______________________________________________
>>> Pharo-project mailing list
>>> [email protected]
>>> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
>>>
>>
>>
>>
>> --
>> Best regards,
>> Igor Stasenko AKA sig.
>>
>> _______________________________________________
>> Pharo-project mailing list
>> [email protected]
>> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
>
> _______________________________________________
> Pharo-project mailing list
> [email protected]
> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
>
_______________________________________________
Pharo-project mailing list
[email protected]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project