# Unexpected BigDecimal rounding issue

**URL:** <https://www.ruby-forum.com/t/unexpected-bigdecimal-rounding-issue/167257>\
**Category:** Ruby\
**Created:** [May 6, 2009, 3:01am UTC](https://www.ruby-forum.com/t/unexpected-bigdecimal-rounding-issue/167257 "2009-05-06T03:01:52Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![samlown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/97f17d/32.png) [@samlown](https://www.ruby-forum.com/u/samlown)\
**Post date:** [May 6, 2009, 3:01am UTC](https://www.ruby-forum.com/t/unexpected-bigdecimal-rounding-issue/167257/1 "2009-05-06T03:01:52Z")

</div>

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?

Cheers, sam

---

<div class="post-metadata">

**Author:** ![samlown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/97f17d/32.png) [@samlown](https://www.ruby-forum.com/u/samlown)\
**Post date:** [May 6, 2009, 5:06am UTC](https://www.ruby-forum.com/t/unexpected-bigdecimal-rounding-issue/167257/2 "2009-05-06T05:06:19Z")

</div>

Hi,

At Wed, 6 May 2009 10:01:54 +0900,  
Samuel L. wrote in [ruby-talk:335867]:

> > > ((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.

BigDecimal is another kind of floating point number, which uses  
decimal base instead of binary, but has finite digits.  
Therefore, it is impossible to represent exactly a recurring  
decimal theoretically.

---

<div class="post-metadata">

**Author:** ![samlown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/97f17d/32.png) [@samlown](https://www.ruby-forum.com/u/samlown)\
**Post date:** [May 6, 2009, 5:30am UTC](https://www.ruby-forum.com/t/unexpected-bigdecimal-rounding-issue/167257/3 "2009-05-06T05:30:52Z")

</div>

On Tue, May 5, 2009 at 9:01 PM, Samuel L. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> 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/](http://talklikeaduck.denhaven2.com/)  
Twitter: [http://twitter.com/RickDeNatale](http://twitter.com/RickDeNatale)  
WWR: [http://www.workingwithrails.com/person/9021-rick-denatale](http://www.workingwithrails.com/person/9021-rick-denatale)  
LinkedIn: [http://www.linkedin.com/in/rickdenatale](http://www.linkedin.com/in/rickdenatale)

---

<div class="post-metadata">

**Author:** ![samlown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/97f17d/32.png) [@samlown](https://www.ruby-forum.com/u/samlown)\
**Post date:** [May 6, 2009, 12:11pm UTC](https://www.ruby-forum.com/t/unexpected-bigdecimal-rounding-issue/167257/4 "2009-05-06T12:11:58Z")

</div>

Yeah I think they would be better off with rationals

Blog: [http://random8.zenunit.com/](http://random8.zenunit.com/)  
Learn: [http://sensei.zenunit.com/](http://sensei.zenunit.com/)  
Twitter: [http://twitter.com/random8r](http://twitter.com/random8r)

On 06/05/2009, at 1:30 PM, Rick DeNatale [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![samlown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/97f17d/32.png) [@samlown](https://www.ruby-forum.com/u/samlown)\
**Post date:** [May 6, 2009, 12:08pm UTC](https://www.ruby-forum.com/t/unexpected-bigdecimal-rounding-issue/167257/5 "2009-05-06T12:08:30Z")

</div>

Rick Denatale wrote:

> On Tue, May 5, 2009 at 9:01 PM, Samuel L. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:
> 
> > Can anyone offer an explanation?
> 
> BigDecimal is still a kind of float, albeit a decimal float rather  
> than a binary float.

Many thanks Nobuyoshi and Rick, that makes complete sense now.

I guess the safest rule of thumb is if you’re doing comparisons for  
humans, use humanized numbers (i.e. integers 🙂

Cheers, sam

---

<div class="post-metadata">

**Author:** ![samlown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/97f17d/32.png) [@samlown](https://www.ruby-forum.com/u/samlown)\
**Post date:** [May 6, 2009, 1:07pm UTC](https://www.ruby-forum.com/t/unexpected-bigdecimal-rounding-issue/167257/6 "2009-05-06T13:07:08Z")

</div>

2009/5/6 Samuel L. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> Many thanks Nobuyoshi and Rick, that makes complete sense now.
> 
> I guess the safest rule of thumb is if you’re doing comparisons for  
> humans, use humanized numbers (i.e. integers 🙂

Or define a maximum error, i.e. do not rely on identical values but  
rather the difference of the quotient.

Kind regards

robert
