# Truncate trouble

**URL:** <https://www.ruby-forum.com/t/truncate-trouble/89353>\
**Category:** Ruby\
**Created:** [March 19, 2007, 8:41pm UTC](https://www.ruby-forum.com/t/truncate-trouble/89353 "2007-03-19T20:41:34Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![russianbandit](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/e36b37/32.png) [@russianbandit](https://www.ruby-forum.com/u/russianbandit)\
**Post date:** [March 19, 2007, 8:41pm UTC](https://www.ruby-forum.com/t/truncate-trouble/89353/1 "2007-03-19T20:41:34Z")

</div>

This

(‘40.12’.to\_f\*100).to\_i

results in this integer :

4011

This is a bit of surprise. I’m using 1.8.4 on windows. Is this a bug?  
Is there another floating type that avoids this problem? I;m not  
seeing anything in the docs that might have warned me.

Greg

---

<div class="post-metadata">

**Author:** ![russianbandit](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/e36b37/32.png) [@russianbandit](https://www.ruby-forum.com/u/russianbandit)\
**Post date:** [March 19, 2007, 8:51pm UTC](https://www.ruby-forum.com/t/truncate-trouble/89353/2 "2007-03-19T20:51:35Z")

</div>

On Mar 19, 1:37 pm, “Greg L.” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> This
> 
> (‘40.12’.to\_f\*100).to\_i
> 
> results in this integer :
> 
> 4011

What I find interesting is that the #inspect result of both f1 and f2  
below are the same, when they internally are clearly not.

irb(main):001:0\> f1 = ‘40.12’.to\_f  
=\> 40.12  
irb(main):002:0\> f1_100  
=\> 4012.0  
irb(main):003:0\> (f1_100).to\_i  
=\> 4011  
irb(main):004:0\> (f1\*100).round.to\_i  
=\> 4012

irb(main):005:0\> 4012.0.to\_i  
=\> 4012

irb(main):006:0\> f2 = ‘40.12000000000001’.to\_f  
=\> 40.12  
irb(main):007:0\> (f2\*100).to\_i  
=\> 4012

---

<div class="post-metadata">

**Author:** ![russianbandit](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/e36b37/32.png) [@russianbandit](https://www.ruby-forum.com/u/russianbandit)\
**Post date:** [March 19, 2007, 9:17pm UTC](https://www.ruby-forum.com/t/truncate-trouble/89353/3 "2007-03-19T21:17:50Z")

</div>

On Tue, Mar 20, 2007 at 04:40:08AM +0900, Greg L. wrote:

> This
> 
> (‘40.12’.to\_f\*100).to\_i
> 
> results in this integer :
> 
> 4011
> 
> This is a bit of surprise. I’m using 1.8.4 on windows. Is this a bug?

Only standard numeric rounding error. The problem is that decimal 0.1  
cannot  
be represented exactly in binary floating point - it’s a recurring  
fraction,  
like 1/3 in decimal - so you get only an approximation.

> Is there another floating type that avoids this problem? I;m not  
> seeing anything in the docs that might have warned me.

irb(main):002:0\> require ‘bigdecimal’  
=\> true  
irb(main):003:0\> f = BigDecimal.new(‘40.12’)  
=\> #BigDecimal:b7cb7548,‘0.4012E2’,8(8)  
irb(main):004:0\> (f\*100).to\_i  
=\> 4012

BigDecimal stores decimal numbers as decimal. It’s not exactly well  
documented though (I only came across it because Ruby on Rails uses it).

Another solution is to multiply all your numbers by 100 at source, i.e.  
works in cents rather than dollars or whatever.

Regards,

Brian.

---

<div class="post-metadata">

**Author:** ![russianbandit](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/e36b37/32.png) [@russianbandit](https://www.ruby-forum.com/u/russianbandit)\
**Post date:** [March 19, 2007, 10:41pm UTC](https://www.ruby-forum.com/t/truncate-trouble/89353/4 "2007-03-19T22:41:30Z")

</div>

On 19.03.2007 20:37, Greg L. wrote:

> seeing anything in the docs that might have warned me.  
> No, that’s a normal rounding error that comes with floats:

irb(main):001:0\> f=‘40.12’.to\_f  
=\> 40.12  
irb(main):002:0\> “%20.10f” % f  
=\> " 40.1200000000"  
irb(main):003:0\> “%40.30f” % f  
=\> " 40.119999999999997442046151263639"  
irb(main):004:0\> “%40.30f” % (f\*100)  
=\> " 4011.999999999999545252649113535881"

If you look at the last line it becomes clear why you get 4011 as  
result.

Kind regards

robert
