The Buckblog

assorted ramblings by Jamis Buck

Infinity

7 February 2007 — 2-minute read

This is hardly an original trick (it’s been mentioned many times before, on countless other blogs) but it is useful enough that it deserves mention yet again.

Ruby won’t let you divide an integer by zero—you’ll get an exception. However, thanks to the IEEE 754 standard for floating point numbers, when you try to divide a float by zero you get a rather special value back:

1
2
puts 1.0/0
#-> Infinity

It’s not a constant though, it’s just how that floating point result is represented as a string. However, you can easily assign that value to a constant:

1
Infinity = 1.0/0

Once you have that, you can use it for all kinds of nifty things; throw it in ranges, use it in comparisons, whatever suits your fancy:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# a rather useless range
everything = -Infinity..Infinity
puts everything.include?(5) #-> true

# use it for representing an unbounded value
storage_limits => { :demo => 0,
  :standard => 250.megabytes,
  :expert => 1.gigabyte,
  :unlimited => Infinity }

if bytes_used < storage_limits[account_level]
  # add another file or something
else
  # display "out of space" message
end

Like I said earlier, it’s old news, but no less handy for that.

Reader Comments

A RCR for this has been added to 1.9/2.0, fwiw:

http://rcrchive.net/rcrs/5

Cool! This blog is a great resource :)

Shouldn’t it rather be “include?(5)” ?

It would be great if this worked within conditions for find method. Like this:

User.find :all, :conditions => {:height => 150..Infinity}

Michael, you’re right, my bad. I’ve corrected the article.

Bobes, I think it’s clearer to just say “height >= 150”. The intention is more manifest, and it’s even fewer characters to type. :)

Nice!

I have stumbled on to this before, and couldn;t figure out why sometimes I would get a ZeroDivisionError and sometimes I would get Infinity. I was even more confused when Inifinity was an uninitialized constant.

For clarification, an integer divided by zero gives you an error, where a float divided by zero gives Infinity.

Thanks for not only helping me sort that out but also show how useful it is.

1
2
3
4
5
6
7
8
9

1.0/0
=> Infinity

0.0/0
=> NaN

0/1
=> 0

I never understood the incongruity in the way a float zero acts vs any other float vs an integer float. I can understand Infinity as a result and I can understand 0 as a result, but NaN for this one case?

Wes, it’s the way that operation is defined. Mathematically speaking, dividing any positive, non-zero value by zero will give you an infinitely large number (you can prove this with limits; dividing some number by smaller and smaller numbers, you get larger and larger quotients). Also, mathematically, dividing any zero by any non-zero value will give you zero. However, zero divided by itself is undefined—it is not a number, and so you get NaN when you try to do so on a computer.

Interesting, is there anyway to encode the concept of Infinity in a database? Looking at your example for storage_limits, it appeared to be possible. (1.0/0).class => Float, so I tried creating a record in a mysql table with a float field => Infinity thinking it would do some kind of magic value, but ActiveRecord turned Infinity into an unescaped string in the sql call.

ActiveRecord::StatementInvalid: Mysql::Error: Unknown column ‘Infinity’ in ‘field list’: INSERT INTO bill_payments (`bill_id`, `paid_bill_id`, `payment`, `is_deleted`) VALUES

Ok, maybe a bad example, I’d like to see someone pay an infinite bill ;)