On Feb 7, 2008, at 6:59 PM, Henry Jones wrote: > Rob Biedenharn wrote: >> On Feb 7, 2008, at 5:26 PM, Henry Jones wrote: >> >>> BigDecimal.new('15.25').to_f == 15.25.to_f also returns false. >>> >>> Substracting both values returns 1.7763... e-015 >>> >>> This is on ruby 1.8.6, Win32. >>> >>> I'm a comp. engineer, so I know it's ultimately related to the >>> binary >>> value of 15.25 which cannot be precisely represented (without an >>> infinite number of bits) , but I'm still amazed that such a simple >>> comparison with a literal value should fail... >> >> >> 15.25 in decimal >> is exactly >> 1111.01 in binary >> >> Seems like a finite number of bits to me ;-) However, the >> construction of 15.25 as a literal is likely something roughly >> (1*10^1 >> + 5*10^0) + (2*10^-1 + 5*10^-2) and those intermediate fractional >> terms are problematic. >> >> Hey, this is Ruby! Roll your own with === >> >> irb> class Float >> irb> def ===(other,eps=0.000000001) >> irb> (self - other.to_f).abs < eps >> irb> end >> irb> end >> => nil >> irb> require 'bigdecimal' >> => true >> irb> 15.25 == BigDecimal.new("15.25") >> => false >> irb> 15.25 === BigDecimal.new("15.25") >> => true >> >> Of course, you'd have to add a similar BigDecimal#=== to get >> symmetry. >> >> -Rob >> >> Rob Biedenharn http://agileconsultingllc.com >> Rob / AgileConsultingLLC.com > > > Apparently the problem lies with BigDecimal, and not the literal > value : > > "%.30f" % 15.25 > will print : "15.250000000000000000000000000000" (not copy pasted, > don't count the zeros =) ) > > but > "%.30f" % BigDecimal("15.25") > will print : "15.250000000000002000000000000000" (notice the '2' in > there) > -- > Posted via http://www.ruby-forum.com/. > Well, now you're pulling in the BigDecimal#to_f which isn't so much a problem in BigDecimal as it is the same limitation of a Float. irb> "%.30f" % 15.25 => "15.250000000000000000000000000000" irb> require 'bigdecimal' => [] irb> "%.30f" % BigDecimal.new('15.25') => "15.250000000000001776356839400250" irb> "%.30f" % BigDecimal.new('15.25').to_f => "15.250000000000001776356839400250" And that just gets back to the problem of building the number up from its decimal pieces: irb> "%.30f" % BigDecimal.new('0.05') => "0.050000000000000002775557561563" irb> "%.30f" % BigDecimal.new('0.2') => "0.200000000000000011102230246252" irb> "%.30f" % BigDecimal.new('5.0') => "5.000000000000000000000000000000" irb> "%.30f" % BigDecimal.new('10.0') => "10.000000000000000000000000000000" (and your '2' is off by two places ;-) -Rob Rob Biedenharn http://agileconsultingllc.com Rob / AgileConsultingLLC.com