Check out the following gist: http://gist.github.com/173975

It's from a Test-Driven Intro To Ruby class I'm working on. Looks good, right?

Not so fast. Check out this spec:

    it "converts body temperature" do
       t = @temperature.ctof(37)
       (t*10).round.should == 986
    end

Why do we have to round? Cause floating-point math is messed up. If we
just follow the pattern and do

      @temperature.ctof(37).should == 98.6

then the spec fails. Buh? See http://www.ruby-forum.com/topic/169330,
especially response http://www.ruby-forum.com/topic/169330#742994 for
more detail.

Without opening up the whole debate over whether it's "correct" in
some language-puritan way, I'd like to propose that the standard RSpec
== matcher be rewritten to compare floats only to a certain degree of
precision... say, 10 decimal places. That could be augmented by a new
"equals_precisely" matcher that does the current == behavior for
floats.

Why do it that way and not just make a new "equals_approximately"
matcher and use it for cases like the above? Because I submit that >99
times out of 100 the expected behavior is for float comparison to
match the rules of regular math, not floating point math.

The ftoc/ctof example is a good case of this: ftoc(98.6) == 37 but
ctof(37) == 98.600000000000008526512829121202. But if I do a puts or
an inspect of that float, it says "98.6" so it's very difficult for
someone who doesn't know any better (i.e. 90% of Ruby programmers and
99% of Ruby students) to figure out what to do. But if you *do* happen
to be doing complicated floating point math then you'll probably know
enough to use "equals_approximately", or at least be able to figure
that out when your ultra-precise spec starts failing.

>> Temperature.new.ctof(37)
=> 98.6
>> Temperature.new.ctof(37) == 98.6
=> false
>> "%.30f" % Temperature.new.ctof(37)
=> "98.600000000000008526512829121202"

Thoughts?

---
Alex Chaffee - [email protected] - http://alexch.github.com
Stalk me: http://friendfeed.com/alexch | http://twitter.com/alexch |
http://alexch.tumblr.com
_______________________________________________
rspec-users mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/rspec-users

Reply via email to