From: Michael Ulm Date: 2007-08-31T15:25:17+09:00 Subject: Re: 0.06 == 0.06 returns false in Ruby? Pe単a wrote: --snip-- > irb(main):010:0> (0.05+0.01) - 0.06 > => 6.93889390390723e-18 > > as mentioned by Dan, careful on comparing floats. And as to any > precision subject, there is what we call significant digits.. > > this floating problem is a faq and is very surprising on such a > very high language such as ruby. can we address this? maybe create > flag like $EPSILON=0 or something, or may flag to revert to rational > or bigdeci like $FLOAT_PROCESSOR=RATIONAL... > Unfortunately, there is no easy solution to this problem. Here is a catalog of often proposed solutions and why they do not work: 1 (proposed by doug meyer in this thread) Always use (x-y).abs < Float::EPSILON as a test for equality. This won't work because the rounding error easily can get bigger than Float::EPSILON, especially when dealing with numbers that are bigger than unity. e.g. y = 100.1 + 0.3 y - 100.4 # => -1.421e-14, while Float::EPSILON = 2.22e-16 2 Always use (x-y).abs < (x.abs + y.abs) * Float::EPSILON) as a test for equality. Better than the first proposal, but won't work if the rounding error gets too large after a complex computation. In addition, (1) and (2) suffer from the problem that x==y and y==z do not imply x==z. 3 Use Bigdezimal This only shifts the problem a few decimal places down, and tests for equality will fail as with the normal floats. 4 Use Rationals Works if you only have to deal with rational operations. But doesn't solve the following x = sqrt(2) y = x + 1 x + 0.2 == y - 0.8 # => false In addition, rational arithmetic can produce huge numbers pretty fast, and this will slow down computations enormously. 5 Use a symbolic math package This could in theory solve the issue with equality, but in practice there is no way to decide that two symbolic representations of a number are the same, like 1 / (sqrt(2) - 1) == sqrt(2) + 1 Also, very, very slow. 6 Use interval arithmetic Gives you strict bounds on your solution, but can't answer x==y. Summing up, when using floating point arithmetic there is no one true way. There is no substitute for understanding numbers and analyzing your problem. HTH, Michael