From: Calamitas Date: 2007-08-30T16:39:54+09:00 Subject: Re: Bug in % (Float)? On 30/08/2007, Morton Goldberg wrote: > On Aug 29, 2007, at 10:14 PM, Pe�a, Botp wrote: > > > From: Charlie Lehardy [mailto:charlie.lehardy@gmail.com] : > > # irb(main):001:0> 1 % 0.1 > > # => 0.1 > > # > > # Shouldn't 1 % 0.1 be 0.0 and not 0.1? > > > > never trust floats in division :) > > ruby tries to be friendly at the expense of more surprises... > > > > irb(main):343:0> system "qri numeric.divmod | head -7" > > --------------------------------------------------------- > > Numeric#divmod > > num.divmod( aNumeric ) -> anArray > > ---------------------------------------------------------------------- > > -- > > Returns an array containing the quotient and modulus obtained by > > dividing num by aNumeric. If q, r = x.divmod(y), then > > > > q = floor(float(x)/float(y) > > > > irb(main):345:0> 1.divmod 0.1 > > => [9, 0.1] > > If Numeric#divmod adhered to the above, the result would be [10.0, > 0.0], so the result is just plain wrong, not a matter of float > inaccuracy. Proof: > > x, y = 1.0, 0.1 > (x/y).floor.to_f # => 10.0 > > > irb(main):347:0> 9*0.1+0.1 > > => 1.0 Mathematically, division goes as follows: given a dividend n, a divisor d, the quotient q and remainder r are defined as follows: n = q * d + r 0 <= r < d The only number required to be integer to make the solution to the equations unique is q. In floating point arithmetic, the first equation is approximately true, usually in as close a way as possible in a certain sense. The second equation is strictly adhered to, you can check: irb(main):001:0> 1.0 % 0.1 < 0.1 => true As for the equation given by ri, it's not intended to be evaluated by Ruby (note how you needed to change where you put the floor function.) Since 0.1 is represented by a float float(0.1) that is slightly larger than 0.1, and 1.0 i represented exactly by float(1.0), float(1.0) / float(0.1) will be slightly smaller than 10 in exact arithmetic, rounding down gives 9. Peter