# Ratio (ratio v2.4.2) View Source

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

It also defines the new <|> operator and (optionally) overrides the arithmetic +, -, * and / operators to work with ints, floats and Rational numbers all alike.

Floats are also automatically coerced into Rationals whenever possible.

And don't worry: If you don't like operator-overloading: There are longhand function aliases available too.

To use the module, use `use Ratio` where you need it.

If you do not want to override the Kernel's built-in math operators, use

``````# Does not override *, /, -, +, div, abs
use Ratio, override_math: false``````

If you just do not want to override the Kernel's built-in inline math operators, use `use Ratio, inline_math: false`

``````# Does not override *, /, -, +
use Ratio, inline_math: false``````

If you do not want the new operator `<|>` to be imported, use

``````# Does not include <|>, construct Rational numbers using Ratio.new(a, b)
use Ratio, operator: false``````

These options can be combined (with `override_math` taking precedence over `inline_math` )

# Link to this section Summary

## Functions

Multiplies two numbers. (one or both of which might be integers, floats or rationals)

Unary plus. Returns num. Coerces the number to a rational if it is a float.

Adds two numbers, one or both of which might be integers, floats or rationals.

Unary minus. Inverts the sign of the given num, which might be an integer, float or rational. Floats are converted to Rationals before inverting the sign.

Subtracts b from a. One or both might be integers, floats or rationals.

Divides a number by another number, one or both of which might be integers, floats or rationals.

Compares two numbers and returns true if the first is less than the second.

Compares two numbers and returns true if the first is less than or equal to the second.

Creates a new Rational number. This number is simplified to the most basic form automatically. If the most basic form has the format `_ <|> 1`, it is returned in integer form.

Compares two numbers and returns true if the first equal to the second.

Compares two numbers and returns true if the first is greater than the second.

Compares two numbers and returns true if the first is greater than or equal to the second.

A Rational number is defined as a numerator and a denominator. Both the numerator and the denominator are integers. If you want to match for a rational number, you can do so by matching against this Struct.

Returns the absolute version of the given number (which might be an integer, float or Rational).

Rounds a number (rational, integer or float) to the largest whole number larger than or equal to num. For negative numbers, this means we are rounding towards negative infinity.

Treats the passed number as a Rational number, and extracts its denominator. For integers, returns `1`.

True if a is equal to b

True if a is equal to b?

Rounds a number (rational, integer or float) to the largest whole number less than or equal to num. For negative numbers, this means we are rounding towards negative infinity.

True if a is larger than or equal to b

True if a is larger than or equal to b

Check if a number is a rational number. Returns false if the number is an integer, float or any other type.

True if a is smaller than b

True if a is smaller than or equal to b

Alias for `Ratio.negate(num)`; follows Numeric behaviour.

Prefix-version of `numerator <|> denominator`. Useful when `<|>` is not available (for instance, when already in use by another module)

Converts the passed number as a Rational number, and extracts its denominator. For integers returns the passed number itself.

returns x to the n th power.

Returns the sign of the given number (which might be an integer, float or Rational)

Converts the given number to a Float. As floats do not have arbitrary precision, this operation is generally not reversible.

Returns a tuple, where the first element is the result of `to_float(number)` and the second is a conversion error.

Returns a binstring representation of the Rational number. If the denominator is `1`, it will be printed as a normal (integer) number.

Returns the integer part of number.

# t()

View Source

## Specs

`t() :: %Ratio{denominator: pos_integer(), numerator: integer()}`

# a * b

View Source

Multiplies two numbers. (one or both of which might be integers, floats or rationals)

## Examples

``````iex> ((2 <|> 3) *  10)
20 <|> 3
iex> ( 1 <|> 3) * (1 <|> 2)
1 <|> 6``````

# +num

View Source

Unary plus. Returns num. Coerces the number to a rational if it is a float.

# a + b

View Source

Adds two numbers, one or both of which might be integers, floats or rationals.

The result is converted to a rational if applicable.

## Examples

``````iex> 2 + 3
5
iex> 2.3 + 0.3
13 <|> 5
iex> 2 + (2 <|> 3)
8 <|> 3``````

# -num

View Source

Unary minus. Inverts the sign of the given num, which might be an integer, float or rational. Floats are converted to Rationals before inverting the sign.

## Examples

``````iex> -10
-10
iex> -10.0
-10
iex> -10.1
-101 <|> 10
iex> -(5 <|> 3)
-5 <|> 3
iex> -123.456
-15432 <|> 125``````

# a - b

View Source

Subtracts b from a. One or both might be integers, floats or rationals.

The result is converted to a rational if applicable.

## Examples

``````iex> 2 - 3
-1
iex> 2.3 - 0.3
2
iex> 2.3 - 0.1
11 <|> 5
iex> (2 <|> 3) - (1 <|> 5)
7 <|> 15``````

# a / b

View Source

Divides a number by another number, one or both of which might be integers, floats or rationals.

The function will return integers whenever possible, and otherwise returns a rational number.

## Examples

``````iex> (1 <|> 3) / 2
1 <|> 6
iex> (2 <|> 3) / (8 <|> 5)
5 <|> 12
iex> 2.0 / 1.0
2``````

# a < b

View Source

Compares two numbers and returns true if the first is less than the second.

## Examples

``````iex> 2 < 3
true
iex> 5 < 5
false
iex> 2.3 < 0.3
false
iex> 10 < (1 <|> 10)
false``````

# a <= b

View Source

Compares two numbers and returns true if the first is less than or equal to the second.

## Examples

``````iex> 2 <= 3
true
iex> 5 <= 5
true
iex> 2.3 <= 0.3
false
iex> 10 <= (1 <|> 10)
false``````

# numerator <|> denominator

View Source

Creates a new Rational number. This number is simplified to the most basic form automatically. If the most basic form has the format `_ <|> 1`, it is returned in integer form.

Rational numbers with a `0` as denominator are not allowed.

Note that it is recommended to use integer numbers for the numerator and the denominator.

## Floats

Tl;Dr: If possible, don't use them.

Using Floats for the numerator or denominator is possible, however, because base-2 floats cannot represent all base-10 fractions properly, the results might be different from what you might expect. See The Perils of Floating Point for more information about this.

Passed floats are rounded to `10` digits, to make the result match expectations better. This number can be changed by adding `max_float_to_rational_digits: 10` to your config file.

See `Ratio.FloatConversion.float_to_rational/2` for more info about float -> rational parsing.

As Float-parsing is done by converting floats to a digit-list representation first, this is also far slower than when using integers or rationals.

## Decimals

To use `Decimal` parameters, the decimal library must be configured in `mix.exs`.

## Examples

``````iex> 1 <|> 2
1 <|> 2
iex> 100 <|> 300
1 <|> 3
iex> 1.5 <|> 4
3 <|> 8``````

# a == b

View Source

Compares two numbers and returns true if the first equal to the second.

## Examples

iex> 2 == 3 false iex> 5 == 5 true iex> 2.3 == 0.3 false iex> 0.1 == (1 <|> 10) true

# a > b

View Source

Compares two numbers and returns true if the first is greater than the second.

## Examples

``````iex> 2 > 3
false
iex> 5 > 5
false
iex> 2.3 > 0.3
true
iex> 10 > (1 <|> 10)
true``````

# a >= b

View Source

Compares two numbers and returns true if the first is greater than or equal to the second.

## Examples

``````iex> 2 >= 3
false
iex> 5 >= 5
true
iex> 2.3 >= 0.3
true
iex> 10 >= (1 <|> 10)
true``````

# %Ratio{}

View Source (struct)

A Rational number is defined as a numerator and a denominator. Both the numerator and the denominator are integers. If you want to match for a rational number, you can do so by matching against this Struct.

Note that directly manipulating the struct, however, is usually a bad idea, as then there are no validity checks, nor wil the rational be simplified.

Use `Ratio.<|>/2` or `Ratio.new/2` instead.

# abs(number)

View Source

Returns the absolute version of the given number (which might be an integer, float or Rational).

## Examples

``````iex>Ratio.abs(-5 <|> 2)
5 <|> 2``````

View Source

Longhand for `Ratio.+/2`

# ceil(num)

View Source

Rounds a number (rational, integer or float) to the largest whole number larger than or equal to num. For negative numbers, this means we are rounding towards negative infinity.

iex> Ratio.ceil(Ratio.new(1, 2)) 1 iex> Ratio.ceil(Ratio.new(5, 4)) 2 iex> Ratio.ceil(Ratio.new(-3, 2)) -1

View Source

# denominator(number)

View Source

Treats the passed number as a Rational number, and extracts its denominator. For integers, returns `1`.

# div(a, b)

View Source

Longhand for `Ratio.//2`

# eq?(a, b)

View Source

True if a is equal to b

# equal?(a, b)

View Source

True if a is equal to b?

# floor(num)

View Source

Rounds a number (rational, integer or float) to the largest whole number less than or equal to num. For negative numbers, this means we are rounding towards negative infinity.

iex> Ratio.floor(Ratio.new(1, 2)) 0 iex> Ratio.floor(Ratio.new(5, 4)) 1 iex> Ratio.floor(Ratio.new(-3, 2)) -2

# gt?(a, b)

View Source

True if a is larger than or equal to b

# gte?(a, b)

View Source

True if a is larger than or equal to b

# is_rational?(arg1)

View Source

Check if a number is a rational number. Returns false if the number is an integer, float or any other type.

To check if a float representation will result in a rational number, combine it with the unary plus operation:

## Examples

``````iex>Ratio.is_rational?(10)
false
iex>Ratio.is_rational?("foo")
false
iex>Ratio.is_rational?(10.0)
false
iex>Ratio.is_rational?(10.234)
false
iex>Ratio.is_rational?(10 <|> 3)
true
iex>Ratio.is_rational?(10 <|> 5)
false
iex>Ratio.is_rational?(+20.234)
true
iex>Ratio.is_rational?(+20.0)
false``````

# lt?(a, b)

View Source

True if a is smaller than b

# lte?(a, b)

View Source

True if a is smaller than or equal to b

# minus(num)

View Source

Alias for `Ratio.negate(num)`; follows Numeric behaviour.

# mult(number1, number2)

View Source

Longhand for `Ratio.*/2`

# negate(num)

View Source

Longhand for `Ratio.-/1`

# new(numerator, denominator \\ 1)

View Source

Prefix-version of `numerator <|> denominator`. Useful when `<|>` is not available (for instance, when already in use by another module)

Not imported when calling `use Ratio`, so always call it as `Ratio.new(a, b)`

To use `Decimal` parameters, the decimal library must be configured in `mix.exs`.

## Examples

``````iex> Ratio.new(1, 2)
1 <|> 2
iex> Ratio.new(100, 300)
1 <|> 3
iex> Ratio.new(1.5, 4)
3 <|> 8
iex> Ratio.new(Decimal.new("123.456"))
15432 <|> 125``````

# numerator(number)

View Source

Converts the passed number as a Rational number, and extracts its denominator. For integers returns the passed number itself.

# pow(x, n)

View Source

## Specs

`pow(number() | t(), pos_integer()) :: number() | t()`

returns x to the n th power.

x is allowed to be an integer, rational or float (in the last case, this is first converted to a rational).

Will give the answer as a rational number when applicable. Note that the exponent n is only allowed to be an integer.

(so it is not possible to compute roots using this function.)

## Examples

``````iex>pow(2, 4)
16
iex>pow(2, -4)
1 <|> 16
iex>pow(3 <|> 2, 10)
59049 <|> 1024``````

# sign(number)

View Source

Returns the sign of the given number (which might be an integer, float or Rational)

This is:

• 1 if the number is positive.
• -1 if the number is negative.
• 0 if the number is zero.

# sub(a, b)

View Source

Longhand for `Ratio.-/2`

# to_float(number)

View Source

## Specs

`to_float(t() | number()) :: float()`

Converts the given number to a Float. As floats do not have arbitrary precision, this operation is generally not reversible.

Not imported when calling `use Ratio`, so always call it as `Rational.to_float(number)`

# to_float_error(number)

View Source

## Specs

`to_float_error(t() | number()) :: {float(), error} when error: t() | number()`

Returns a tuple, where the first element is the result of `to_float(number)` and the second is a conversion error.

The conversion error is calculated by subtracting the original number from the conversion result.

## Examples

``````iex> Ratio.to_float_error(Ratio.new(1, 2))
{0.5, 0}
iex> Ratio.to_float_error(Ratio.new(2, 3))
{0.6666666666666666, 1 <|> 30000000000}``````

# to_string(rational)

View Source

Returns a binstring representation of the Rational number. If the denominator is `1`, it will be printed as a normal (integer) number.

## Examples

``````iex> Ratio.to_string 10 <|> 7
"10 <|> 7"``````

# trunc(num)

View Source

## Specs

`trunc(t() | number()) :: integer()`

Returns the integer part of number.

## Examples

``````iex> Ratio.trunc(1.7)
1
iex> Ratio.trunc(-1.7)
-1
iex> Ratio.trunc(3)
3
iex> Ratio.trunc(Ratio.new(5, 2))
2``````