On Thu, Jan 26, 2012 at 7:33 PM, Intransition [email protected]
wrote:
Seriously? You blame the example? Reminds me of that old joke.
Patient: “Doctor, it hurts when I do this.”
Doctor: “Well, don’t do that!”The problem is you’re looking at in only as an engineer might, dealing with
very small deltas. But as animplementerof such a method as #close_to? or
#approx? I would never assume there are no valid applications that are
concerned with bulkier scales.
We’re talking at cross purposes here, and Yossef’s impoliteness
doesn’t help. Implementing #close_to? or #approx? is trivial, and
yes, it needs to provide for different applications. But talking
about Float#approx?, you may as well be talking about String#approx?,
as in “foobar”.approx?(“foobaz”).
But that has nothing to do with this thread. (Of course, it’s a long
thread and can take in different aspects of the topic, but…) You
started the thread complaining that 1.1 - 1.0 was not equal to 0.1,
that Ruby lacked “math skills”.
The answer to that is: don’t use Float.==. It’s a revealing answer,
because the natural follow-up question is “Why does the language
provide a useless method but not provide a useful replacement?”. When
it comes to floats, everyone has to be aware of their shortcomings and
roll their own comparison method.
If your application demands you use some implementation of #approx?
with a specific delta – e.g. collision detection in a game – then
we’re talking about an application-specific problem that is NOT caused
by the underlying representation of floats.
If your application would like to use “x == 4.75” but can’t, this is
NOT an application-specific problem; it’s a float representation
problem.
“x == 4.75” needs to be replaced by something. Should it be
“x.approx?(4.75)” ? No. That’s using an application-layer approach
to a non-application-layer problem.
“x == 4.75” should be replaced with x.essentially_equals?(4.75), which
tackles the representation problem, not the non-existent application
problem.
Mixing up these ideas makes for a confusing and (unfortunately)
potentially impolite discussion.
The problem is, Ruby doesn’t implement Float#essentially_equals?.
(Yes, a better name would be good.) If it did, there would be an
argument for simply defining Float.== in that way. The current
definition of Float.== is insufficient for its task, and simply
reflects Ruby’s C heritage. I wonder if anybody would be put out if
it were redefined to be more useful and less surprising.
Gavin