On Fri, Mar 6, 2009 at 7:42 PM, Christopher Dicely <cmdicely / gmail.com> wrote: > 2009/3/6 S2 <some.r / ndom.mail.invalid.net>: >> ruby 1.8.7 (2008-08-11 patchlevel 72) [i486-linux] >> >>>> 2000-1992.2 >> => 7.79999999999995 >> >> > > The use of inexact floating point numbers by default in Ruby (which > follows C and most, but not all, other programming languages) is a > design choice, not a bug. One might dispute whether or not its a good > design choice (personally, I prefer Scheme's numeric tower and exact > numbers by default with conversion to inexact numbers only when an > inexact operation is applied to an exact number or an explicit > designation of an inexact number is given), but its a point about > which people could debate endlessly, and since BigDecimal is at least > in the standard library, its not a matter of whether Ruby can do exact > math, but just how verbose the code is to do it. > > ex: > > require 'bigdecimal' > require 'bigdecimal/math' > > class BigDecimal > # BigDecimal.to_s is ugly > def pretty > digits, magnitude = to_s.split('.')[1].split('E') > magnitude=magnitude.to_i > digits.insert(0,'0'*[(1-magnitude),0].max) > digits.insert([magnitude,1].min,'.') > end > end > > include BigMath > > (2000-BigDecimal('1992.2')).pretty > => "7.8" > > Or, while that works for the case presented, if you want it to work right in general: class BigDecimal def pretty return to_i.to_s if self==to_i digits, magnitude = to_s.split('.')[1].split('E') magnitude = magnitude.to_i digits.insert(0,'0'*[(1-magnitude),0].max) digits.insert([magnitude, 1].max,'.') end end