In computing, Ruby is supposed to convert from Fixnum to Bignum when numbers go beyond Fixnum. For older versions of Ruby, this does not work with the ** operator:
$ ruby --version ruby 1.8.7 (2012-02-08 patchlevel 358) [universal-darwin12.0] $ irb >> 2 ** 62 => 4611686018427387904 >> 2 ** 63 => -9223372036854775808 >> 2 ** 64 => 0
Where this fails depends on the size of the word architecture. 64-bit words on iMac in this example. Internally, Fixnum is cast to a long integer, and the statement is processed to be long. Long overflows at the size of a word, and Ruby ruthlessly copes with this, returning 0.
Note that the * operator works correctly (conversion to Bignum), where ** fails:
>> a = 2 ** 62 => 4611686018427387904 >> 2 ** 63 => -9223372036854775808 >> a * 2 => 9223372036854775808 >> 2 ** 64 => 0 >> a * 4 => 18446744073709551616
The transition to the new version of Ruby will be fixed. If you cannot upgrade to a newer version, avoid using Fixnum and ** with more authority.
coates
source share