Home

Awesome

Ratio

hex.pm version Documentation ci

This library allows you to use Rational numbers in Elixir, to enable exact calculations with all numbers big and small.

Ratio follows the Numeric behaviour from Numbers, and can therefore be used in combination with any data type that uses Numbers (such as Tensor and ComplexNum).

Using Ratio

Ratio defines arithmetic and comparison operations to work with rational numbers.

Rational numbers can be created by using Ratio.new/2, or by calling mathematical operators where one of the two operands is already a rational number.

Shorthand infix construction operator

Since version 4.0, Ratio no longer defines an infix operator to create rational numbers. Instead, rational numbers are made using Ratio.new, and as the output from using an existing Ratio struct with a mathematical operation.

If you do want to use an infix operator such as <~> (supported in all Elixir versions) or <|> (deprecated in Elixir v1.14, the default of older versions of the Ratio library)

you can add the following one-liner to the module(s) in which you want to use it:

defdelegate numerator <~> denominator, to: Ratio, as: :new

Basic functionality

Rational numbers can be manipulated using the functions in the Ratio module.

iex> Ratio.mult(Ratio.new(1, 3), Ratio.new(1, 2))
Ratio.new(1, 6)
iex> Ratio.div(Ratio.new(2, 3), Ratio.new(8, 5))
Ratio.new(5, 12)
iex> Ratio.pow(Ratio.new(2), 4)
Ratio.new(16, 1)

The Ratio module also contains:

Inline Math Operators and Casting

Ratio interopts with the Numbers library: If you want to overload Elixir's builtin math operators, you can add use Numbers, overload_operators: true to your module.

This also allows you to pass in a rational number as one argument and an integer, float or Decimal (if you have installed the Decimal library), which are then cast to rational numbers whenever necessary:

defmodule IDoAlotOfMathHere do
  defdelegate numerator <~> denominator, to: Ratio, as: :new
  use Numbers, overload_operators: true

  def calculate(input) do
     num = input <~> 2
     result = num * 2 + (3 <~> 4) * 5.0
     result / 2
  end
end

iex> IDoAlotOfMathHere.calculate(42)
Ratio.new(183, 8)

Installation

The package can be installed from hex, by adding :ratio to your list of dependencies in mix.exs:

    def deps do
      [
        {:ratio, "~> 4.0"}
      ]
    end

Changelog

Difference with the 'rational' library

Observant readers might notice that there also is a 'rational' library in Hex.pm. The design idea between that library vs. this one is a bit different: Ratio hides the internal data representation as much as possible, and numbers are therefore only created using Ratio.new/2. This has as mayor advantage that the internal representation is always correct and simplified.

The Ratio library also (optionally) overrides (by virtue of the Numbers library) the built-in math operations +, -, *, /, div, abs so they work with combinations of integers, floats and rationals.

Finally, Ratio follows the Numeric behaviour, which means that it can be used with any data types that follow Numbers.