Thanks Trygve and Andres,
I also agree that comparing float is a bad practice.
It is even worse outside squeak because of intel registers extra bits for
example (result will depend on use of registry or not and hence on compiler
optimization and neighbour code).
The question should (2 = 2.0) and (2.0 = 2.0) is interesting...
In my opinion, there are cases when float comparison is usefull: precondition
to guard against an exception (zero divide or whatever).
First solution i was proposing is to continue to answer true to that, since
it can be valid as long as no inexact arithmetic took place (depends how we
made the 2.0, but the conversion from string is OK).
I even happened to use float arithmetic once just to have cheap integer
arithmetic on 53bits (OK, shame on me, but it works).
Hence we can modify = so as to answer true only in exact arithmetic sense
( (1/2)=0.5 but (1/10)~=0.1 ).
Concerning Set and hash code, we can make it working accordingly, using Float
But there is a performance penalty (factor 100 on hash before optimization).
I am not totally opposed to more radical solution you seem suggesting: (2 =
2.0) never answer true.
In this case, we can still have efficient hash for comparing (2.0=2.0), and
do not have to bother with Integer and Fraction.
There are some cases when i would like such a behavior:
For example, i want to use compiler to repeatedly evaluate an automatically
generated mathematical formula, but i face the too many literals byte code
limit. I can reduce number of literals by eliminating double entries, and use
a Set for that. Here, i do not want literal #(2.0) being replaced with #(2),
and in this case i would prefer 2~=2.0... (Yes, i can have array literals in
my formula due to matrix).
The only penalty of second solution is to break all bad-practice code...
It is always possible to force a conversion toward exact or inexact
But people can have programmed with automatic conversion in mind...
For example, protect against zero divide with a~=0... (yes a isZero would be
better in this case).
Is there a lot such code in Squeak ? Hard to say...
We must inquire that and ask other squeakers opinion.
It is not a thin change...
Le Mercredi 29 Mars 2006 08:13, Trygve Reenskaug a écrit :
> I wholeheartedly agree. We have used tolerance tests for floats since 1962
> because equality tests are meaningless. = for floats should give error.
> At 06:01 29.03.2006, Andres wrote:
> >Hello ncellier,
> >Tuesday, March 28, 2006, 7:25:46 AM, you wrote:
> >nic> [number hashing is broken]
> >nic> What is your opinion ?
> >IMHO... sometimes it may be convenient to have 2 = 2.0, but since they
> >represent different intentions, I would not expect that to happen.
> >Why should a perfectly specified integer be equal to, possibly, the
> >result of carrying calculations without infinite precision? What
> >would it mean if theGreatDoublePrecisionResult = 2? Wouldn't it be
> >more interesting (and precise) to ask laysWithin: epsilon from: 2?
> >In other words, comparing constants makes it look much simpler than
> >what it really is. Reading something like anInteger = 2.0 would be,
> >from my point of view, highly questionable because it is an assertion
> >that an approximation has an *exact* value. Nonsense.
> > >From a more pragmatic point of view, there is also the issue of 2 =
> >2.0, but things like
> > (1 bitShift: 1000) - 1
> >cannot be equal to any floating point number supported by common
> >hardware. Thus, exploiting anInteger = aFloat is intention obscuring
> >by definition since it may or may not work depending on the integer.
> >Again, highly questionable.
> >In short: floating point numbers *may* be equal to integers, but the
> >behavior of #= cannot be determined a priori. Since the behavior of
> >#= does not imply a relationship of equivalence, the behavior of #hash
> >is inconsequential.
> >Adding integers and floats to a set gets messed up. So we have two
> >options... a) don't do it because it is intention obscuring... or b)
> >make integers never be equal to floating point numbers.
> >Same deal with fractions and the like.
> >Best regards,
> > Andres mailto:firstname.lastname@example.org