factorial(21) and Mac System Ruby

I just got a new macbook air and discovered this problem with the system ruby. Here’s a simple implementation of factorial.

1
2
3
4
def fact(n)
  return 1 if n.between?(0, 1)
  (2..n).inject(:*)
end

When you run it in irb it does what you’d expect:

1
2
3
4
5
6
7
8
9
10
11
12
>> fact(1)
=> 1
>> fact(0)
=> 1
>> fact(2)
=> 2
>> fact(5)
=> 120
>> fact(10)
=> 3628800
>> fact(20)
=> 2432902008176640000

Until the result won’t fit in a Fixnum and needs to fit in a big num. Then it overflows.

1
2
>> fact(21)
=> -4249290049419214848

My macbook shipped with this version of ruby.

ruby 1.8.7 (2012-02-08 patchlevel 358) [universal-darwin12.0]

This bug isn’t in ruby, its in the version that Apple is shipping on the newest macbooks. Using rbenv I installed the same patch version and re-ran the factorials.

1
2
3
4
5
6
>>fact(1)
=> 1
>>fact(20)
=> 2432902008176640000
>>fact(21)
=> 51090942171709440000