From: Robert Klemme Date: 2007-08-31T21:02:25+09:00 Subject: Re: 0.06 == 0.06 returns false in Ruby? 2007/8/31, Pe�a, Botp : > From: Robert Klemme [mailto:shortcutter@googlemail.com] > # And who decides about the size of epsilon and which algorithm to > # choose? There is no one size fits all answer to that hence leaving > # Float#== the way it is (i.e. compare for exact identical values) is > # the only viable option. Otherwise you would soon see similar > # questions on the list, i.e., "how come it sometimes works and > # sometimes it doesn't". And they become more difficult to answer as > # the cases are likely less easy to spot / explain. > > indeed :( > > maybe i'm not "realistic" but i thought > > 0.05 + 0.01 == 0.06 => false > > was "unrealistic" enough for a simple and plain 2 decimal arithmetic. Even people w zero-know on computers would laugh about it (yes, try explaining it to your wife or kids, eg). That's probably the exact reason why not your wife or kids write software but people who are (hopefully) experts. :-) If you study computer sciences you'll typically hit the topic of numeric issues at some point. > For simple math (eg those dealing w money): > i can live w slowness in simple math (quite a paradox if you ask me). > i can live w 1/3 == 0.3333333333 =>false > or that sqrt(2) == 1.1414213562 => false > i use bigdecimal. bigdecimal handles 0.05 + 0.01 == 0.06 => true > > For complex math, > i can live w slowness (no question there). > bigdecimal easily handles sqrt(2) at 100 digits: 2.sqrt(100) => # so yes, i still use bigdecimal for complex math. > > so regardless, of whether its simple or complex (or "highly precise" or not), i use bigdecimal. counting ang looping otoh has no problem w me since fixnum/bignum handles this flawlessly. (Also, note that big RDBMS like oracle and postgresql use BCD and fixed pt math for numerics). > > So, my question probably is (maybe this could be addressed to Matz): How can i make ruby use a particular arithmetic, like bigdecimal eg, so that literals like 1.05, and operations like 1+1.01 are now handled as bigdecimals. Well, you could provide your formula as strings and convert it to something that creates BigDecimals along the way, like irb(main):015:0> "0.01+0.05".gsub(%r{\d+(?:\.\d*)?}, "BigDecimal.new('\\&')") => "BigDecimal.new('0.01')+BigDecimal.new('0.05')" irb(main):016:0> eval("0.01+0.05".gsub(%r{\d+(?:\.\d*)?}, "BigDecimal.new('\\&')")) => # # note this is of course not a proper solution since the RX does not match all valid floats Kind regards robert