Let’s start by taking a look at the class hierarchy of all the number related classes in Ruby:
Numeric # Parent for all of the number classes. Integer # Object representing integer numbers. Float # Object representing imprecise decimal numbers. Complex # Object representing imaginary numbers. Rational # Object representing rational numbers (fractions, in simple words). BigDecimal # Object providing arbitrary-precision floating-point decimal arithmetic. It's part of Ruby Standard Library.
Numeric is the class from which all higher-level numeric classes should inherit.
An Integer object represent math integer value:
>> Integer(1) => (1)
Let’s check hierarchy.
ancestors method gets parent classes and modules, and as we don’t need modules we’ll substact them:
>> Integer.ancestors - Integer.included_modules => [Integer, Numeric, Object, BasicObject]
There were Fixnum & Bignum before Ruby 2.4 unified Fixnum & Bignum into the same class (Integer) in 2016:
Actucally, you still can see hierarchy, but will see “Integer” as current class:
>> Fixnum.ancestors - Fixnum.included_modules => [Integer, Numeric, Object, BasicObject]
Why do we need different classes? It’s Ruby implementation detail for optimization purpose. The same optimizations still exist, but it’s compiler optimization, i.e. behind the scenes, invisible to the programmer. Basically, Fixnums are fast and Bignums are slower, and the implementation automatically switches back and forth between them. Since Ruby 2.4 you don’t ask Fixnum or Bignum, you just get one or the other, depending on whether your integer fits into the restricted size of a Fixnum or not.
Ruby docs says about Float:
A Float object represents a sometimes-inexact real number using the native architecture’s double-precision floating point representation.
This is not Ruby’s fault. Floats in general suffer from this type of rounding error, for example:
>> (1.0-0.1) == 0.9 => false
In math there is a concept of Complex numbers. Complex numbers are the numbers that are expressed in the form of
b are real numbers and
i is an imaginary number.
Complex object is used to represent this mathematical concept in Ruby.
>> Complex(1) => (1+0i)
It’s an object to represent mathematical rational numbers. A rational number is a number that can be represented as a pair of integer numbers:
b > 0), where
a is the numerator and
b is the denominator. Integer number
a equals rational number
>> Rational(1) => (1/1)
BigDecimal provides arbitrary-precision floating-point decimal arithmetic.
>> BigDecimal(1) => 0.1e1