# Ruby to\_i problem

**URL:** <https://www.ruby-forum.com/t/ruby-to-i-problem/183572>\
**Category:** Ruby\
**Created:** [February 16, 2010, 7:16pm UTC](https://www.ruby-forum.com/t/ruby-to-i-problem/183572 "2010-02-16T19:16:12Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![basic](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/58956e/32.png) [@basic](https://www.ruby-forum.com/u/basic)\
**Post date:** [February 16, 2010, 7:16pm UTC](https://www.ruby-forum.com/t/ruby-to-i-problem/183572/1 "2010-02-16T19:16:12Z")

</div>

I’m having an issue with a float being converted to an int,

The maths is part of a vector rotation of a little video game, which x,y  
coords are rotated at a given angle.

For what ever reason the first instance gives an error, and every  
instance there after works as it should

This cant be right?

ruby 1.8.7  
[irb]

# This works the way I would think

> > 1.0.o\_i  
> > =\> 1

# This doesn’t

> > x = -1  
> > y = -1  
> > angle = 90 \* Math::PI / 180  
> > n\_x = (Math::cos(angle) \* x) - (Math::sin(angle) \* y)  
> > =\> 1.0

# this is where its werid

> > n\_x.to\_i  
> > =\> 0  
> > [/irb]

any further 1.0.to\_i works

---

<div class="post-metadata">

**Author:** ![basic](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/58956e/32.png) [@basic](https://www.ruby-forum.com/u/basic)\
**Post date:** [February 16, 2010, 7:31pm UTC](https://www.ruby-forum.com/t/ruby-to-i-problem/183572/2 "2010-02-16T19:31:21Z")

</div>

Phil Cooper-king wrote:

> any further 1.0.to\_i works

## You’re experiencing IEEE Floating point aritmetic. Look at this example:

## ruby -v: ruby 1.9.1p378 (2010-01-10 revision 26273) [x86\_64-linux] irb(main):001:0\> x = -1 =\> -1 irb(main):002:0\> y = -1 =\> -1 irb(main):003:0\> angle = 90 \* Math::PI / 180 =\> 1.5707963267949 irb(main):004:0\> n\_x = (Math::cos(angle) \* x) - (Math::sin(angle) \* y) =\> 1.0 irb(main):005:0\> sprintf("%.50f", n\_x) =\> “0.99999999999999988897769753748434595763683319091797” irb(main):006:0\> n\_x.to\_i =\> 0 irb(main):007:0\> n\_x.round =\> 1 irb(main):008:0\> sprintf("%.50f", 1.0) =\> “1.00000000000000000000000000000000000000000000000000” irb(main):009:0\>

Your result isn’t that exactly 1 as you think.

Marvin

---

<div class="post-metadata">

**Author:** ![basic](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/58956e/32.png) [@basic](https://www.ruby-forum.com/u/basic)\
**Post date:** [February 16, 2010, 7:39pm UTC](https://www.ruby-forum.com/t/ruby-to-i-problem/183572/3 "2010-02-16T19:39:28Z")

</div>

On Tue, Feb 16, 2010 at 10:16 AM, Phil Cooper-king [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> For what ever reason the first instance gives an error, and every  
> instance there after works as it should

What You Think Is Happening Is Not What Is Actually Happening 🙂

> ruby 1.8.7  
> [irb]
> 
> # This works the way I would think
> 
> > > 1.0.o\_i  
> > > =\> 1

Yep, and every time you say 1.0.to\_i you will get 1.

> # This doesn’t
> 
> > > x = -1  
> > > y = -1  
> > > angle = 90 \* Math::PI / 180  
> > > n\_x = (Math::cos(angle) \* x) - (Math::sin(angle) \* y)  
> > > =\> 1.0

irb is showing you an approximation. It’s confusing because irb is  
showing you n\_x to be 1.0, when in fact:

> > sprintf “%0.25f”, n\_x  
> > =\> “0.9999999999999998889776975”

> # this is where its werid
> 
> > > n\_x.to\_i  
> > > =\> 0

Yep:

> > 0.9.to\_i  
> > =\> 0

> any further 1.0.to\_i works

1.0.to\_i and n\_x.to\_i (from your example) are two different things.

Search the group archives for “floating point”, you’re sure to find a  
huge pile of other people with similar problems, and likely good  
solutions.

Ben

---

<div class="post-metadata">

**Author:** ![basic](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/58956e/32.png) [@basic](https://www.ruby-forum.com/u/basic)\
**Post date:** [February 16, 2010, 7:43pm UTC](https://www.ruby-forum.com/t/ruby-to-i-problem/183572/4 "2010-02-16T19:43:34Z")

</div>

On Tue, Feb 16, 2010 at 7:16 PM, Phil Cooper-king [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> > > angle = 90 \* Math::PI / 180  
> > > n\_x = (Math::cos(angle) \* x) - (Math::sin(angle) \* y)  
> > > =\> 1.0
> 
> # this is where its werid
> 
> > > n\_x.to\_i  
> > > =\> 0  
> > > [/irb]
> 
> any further 1.0.to\_i works

You are facing a problem about the inaccuracy inherent to floating  
point numbers:

irb(main):001:0\> 0.9999.to\_i  
=\> 0  
irb(main):002:0\> x = -1  
=\> -1  
irb(main):003:0\> y = -1  
=\> -1  
irb(main):004:0\> angle = 90 \* Math::PI / 180  
=\> 1.5707963267949  
irb(main):005:0\> n\_x = (Math::cos(angle) \* x) - (Math::sin(angle) \* y)  
=\> 1.0  
irb(main):009:0\> “%.20f” % n\_x  
=\> “0.99999999999999988898”  
irb(main):010:0\>  
irb(main):010:0\> n\_x  
=\> 1.0

n\_x is very close to 1.0 but it’s not. to\_i rounds the number down, so  
you get 0. You can check the archives for a more thorough explanation  
about this, there’s been plenty of discussion in the past.

Jesus.

---

<div class="post-metadata">

**Author:** ![basic](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/58956e/32.png) [@basic](https://www.ruby-forum.com/u/basic)\
**Post date:** [February 16, 2010, 7:54pm UTC](https://www.ruby-forum.com/t/ruby-to-i-problem/183572/5 "2010-02-16T19:54:20Z")

</div>

thanks guys, this makes it clear
