Say you're on a 64-bit system. In that case, any numbers with absolute
value less than 2^62 will be a Fixnum:
(2**62 - 1).class
=> Fixnum
Fixnums are usually described as "immediate" values. In MRI at least,
their value is encoded in their object ID using 2n+1:
(-2..2).map { |e| [e, e.object_id] }
=> [[-2, -3], [-1, -1], [0, 1], [1, 3], [2, 5]]
Anything greater than or equal to 2^62 in absolute value will come out
as a Bignum, which are "normal" instances of the Bignum class.
(2**62).class
=> Bignum
There's no such object ID stunt here:
(0..4).map { |e| [(2**62 + e), (2**62 + e).object_id] }
=> [[4611686018427387904, 70120613511800], [4611686018427387905,
70120613511580], [4611686018427387906, 70120613511360],
[4611686018427387907, 70120613511140], [4611686018427387908,
70120613510920]]
(For n-bit systems, Fixnum values are stored with n-1 bits since 1 bit
is used by the VM, so the range of values for a Fixnum is (-2^(n-1) +
1, 2^(n-1) - 1). Not sure if this is exactly the same with other Ruby
implementations.)
Integer is the superclass of both, for cases where you wish to simply
reason about integers:
Bignum.ancestors
=> [Bignum, Integer, Numeric, Comparable, Object, Kernel, BasicObject]
Fixnum.ancestors
=> [Fixnum, Integer, Numeric, Comparable, Object, Kernel, BasicObject]
Numeric is to cover Integers and other types of number:
Float.ancestors
=> [Float, Numeric, Comparable, Object, Kernel, BasicObject]
For example, Complex in the stdlib mathn library is a subclass of Numeric:
require "mathn"
=> true
Complex(2, 5)
=> (2+5i)
Complex.ancestors
=> [Complex, Numeric, Comparable, Object, Kernel, BasicObject]
Hope that helps!