Bugs item #10935, was opened at 2007-05-20 11:13
You can respond by visiting: 
http://rubyforge.org/tracker/?func=detail&atid=1698&aid=10935&group_id=426

Category: Core
Group: 1.8.x
Status: Open
Resolution: None
Priority: 3
Submitted By: Boris Schmid (bor_)
Assigned to: Nobody (None)
Summary: eval("0.0025 + 9 * 0.0025") === 0.025  => false

Initial Comment:
Eval is being (inconsistently) strange. 

It's acting normal when I do the (8 * 0.0025) example, and not acting normally when I do the (9 * 0.0025) example. Plenty of other combinations where it repeatedly does the same.


boris:alive:~:irb
irb(main):001:0> eval("0.0025 + 9 * 0.0025")
=> 0.025
irb(main):002:0> eval("0.0025 + 9 * 0.0025") === 0.025
=> false
irb(main):003:0> eval("0.0025 + 8 * 0.0025")
=> 0.0225
irb(main):004:0> eval("0.0025 + 8 * 0.0025") === 0.0225
=> true
irb(main):005:0> exit
boris:alive:~:ruby -v
ruby 1.8.5 (2006-12-25 patchlevel 12) [i686-linux]


Same for ruby 1.8.5 (2006-12-25 patchlevel 12) [i386-mswin32]
Same for ruby 1.8.6 (2006-12-25 patchlevel 12) [i386-mswin32]

For windows ruby 1.8.6, the below sample give some more insight into the bug:

irb(main):001:0> eval("1 + 9 * 1")
=> 10
irb(main):002:0> eval("1 + 9 * 1") === 10
=> true
irb(main):003:0> eval("0.1 + 9 * 0.1")
=> 1
irb(main):004:0> eval("0.1 + 9 * 0.1") === 1
=> true
irb(main):005:0> eval("0.01 + 9 * 0.01") === 0.1
=> false
irb(main):006:0> exit


----------------------------------------------------------------------

Comment By: Brad Greenlee (bgreenlee)
Date: 2007-05-20 13:07

Message:
That newspost was interesting...thanks.

If you need to work with precise decimal numbers, use BigDecimal. Note, though, that doing calculations with BigDecimals is significantly slower than with floats.

----------------------------------------------------------------------

Comment By: Boris Schmid (bor_)
Date: 2007-05-20 12:29

Message:
Thanks for the article, about halfway reading it, and an old
newspost I googled
(http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/41404).


Basically, the rule seems to be to be wary when using == (or
===) when working with floats. I'll print it out on the wall
across my computer. Thanks!

irb(main):009:0> 0.01 + 1 * 0.01
=> 0.02
irb(main):010:0> 0.01 + 1 * 0.01 === 0.02
=> true
irb(main):011:0> 0.01 + 2 * 0.01 === 0.03
=> true
irb(main):012:0> 0.01 + 3 * 0.01 === 0.04
=> true
irb(main):013:0> 0.01 + 4 * 0.01 === 0.05
=> true
irb(main):014:0> 0.01 + 5 * 0.01 === 0.06
=> false
irb(main):015:0> 0.01 + 6 * 0.01 === 0.07
=> false
irb(main):016:0> 0.01 + 7 * 0.01 === 0.08
=> true
irb(main):017:0> 0.01 + 8 * 0.01 === 0.09
=> true
irb(main):018:0> 0.01 + 9 * 0.01 === 0.1
=> false
irb(main):019:0> 0.1 === 0.10
=> true
irb(main):020:0> 0.01 + 10 * 0.01 === 0.11
=> true
irb(main):021:0> 0.01 + 11 * 0.01 === 0.12
=> true

Given the above pattern, it seems wise to be wary when using
== or === with floats ;)

----------------------------------------------------------------------

Comment By: Brad Greenlee (bgreenlee)
Date: 2007-05-20 11:22

Message:
http://docs.sun.com/source/806-3568/ncg_goldberg.html

----------------------------------------------------------------------

You can respond by visiting: 
http://rubyforge.org/tracker/?func=detail&atid=1698&aid=10935&group_id=426