From: Heesob Park Date: 2009-03-03T18:13:35+09:00 Subject: [ruby-core:22639] Re: suggestions for float 2009/3/3 Brent Roman : > > OK. ��I apologize in advance. ��Soapbox on... > > I, for one, like Ruby's current approach to numeric type conversions. > There is an automatic promotion from Fixnum to Bignum to prevent ��overflow. > (a nice feature borrowed from SmallTalk) > > However, as others have pointed out, there is no analogous promotion between > discrete, countable Integer types and Floats. ��This is because all Floats > are *approximations* of abstract, continuous Real numbers. > > Floats are imprecise by design. ��They are intended to represent measured > quantities, not countable objects. ��Any real valued measurement is likely to > have more error in its underlying physics than the 8-byte binary floating > point format Ruby uses to approximate that value. > > Floats should not be used for counting *anything* discrete. ��Not pennies, > not array elements, not machine states. ��(ok, maybe pennies if you are > dealing with current stock prices :-) > > Sure, they can approximate 1.0 fairly well. ��But, 1.1 is an inexact > repeating binary fraction. > > A variant of the float to string conversion that tries to preserve all the > binary information would certainly be useful, but not as the default to_s > method. ��That is, unless you think that: > > irb> ��2.1 - 3.0 > -0.8999999999999999 > > would not be "surprising"! ��(well, at least annoying) > > Then, of course, there remains the question of efficiency. ��Many simple > iterative numerical algorithms will cause BigDecimal and Rational numbers to > balloon in bytes required as they struggle to maintain perfect accuracy. > And, as they become bigger in memory, they will also become slower. ��Think > of numerical integration, for example, ��or most any sort of successive > approximation, in general. > > But, theoretical niceties aside, most plain folks are surprised when their > fancy computer says: > > �� 2.1 - 3.0 ��!= -0.9 > > What would fix this problem while still preserving efficiency and keep us > numerical nerds happy? > One possible fix is something like this: class Float alias :plus :+ alias :minus :- def +(a) self.plus(a).to_s.to_f end def -(a) self.minus(a).to_s.to_f end end irb> 2.1 - 3.0 == -0.9 => true Regards, Park Heesob