From: Rick DeNatale Date: 2009-05-06T12:30:15+09:00 Subject: Re: Unexpected BigDecimal rounding issue On Tue, May 5, 2009 at 9:01 PM, Samuel Lown wrote: > Hi, > > Some more not so fun rounding issues. > > Using Floats: > >>> ((30 / 1.16) * 1.16) == 30 > => true > > Cool, so you'd think it would work with BigDecimal: > >>> ((30 / BigDecimal("1.16")) * BigDecimal("1.16")) == 30 > => false >>> ((30 / BigDecimal("1.16")) * BigDecimal("1.16")).to_s > => "30.0000000000000000000000002" > > I'm clearly missing something here as I thought BigDecimal was supposed > to fix this type of thing. > > Tested in: > ruby 1.8.6 (2008-03-03 patchlevel 114) [universal-darwin9.0] > ruby 1.9.1p0 (2009-01-30 revision 21907) [i386-darwin9.6.0] > > Can anyone offer an explanation? BigDecimal is still a kind of float, albeit a decimal float rather than a binary float. So it helps with problems when the fractional part of a number can be expressed exactly as a finite string of decimal digits, but just as certain fractional parts can't be expressed exactly as a finite string of binary digits, there are some which have the same problem when the base is 10. For example 1/3 cannot be expressed as a decimal float, no matter how many digits 0.33333..... Similarly 3000/116 (which is the same as 30/1.16) can't be expressed by a finite sequence of decimal digits. It comes out as 25.862068965517241379310344827[5862068965517241379310344827]... where the digits in the brackets repeat infinitely. -- Rick DeNatale Blog: http://talklikeaduck.denhaven2.com/ Twitter: http://twitter.com/RickDeNatale WWR: http://www.workingwithrails.com/person/9021-rick-denatale LinkedIn: http://www.linkedin.com/in/rickdenatale