Numbers (numbers v5.2.4)

Allows you to use arithmetical operations on any type that implements the proper protocols.

For each arithmetical operation, a different protocol is used so that types for which only a subset of these operations makes sense can still work with those.

Basic Usage

Usually, Numbers is used in another module by using alias Numbers, as: N, followed by calling the functions using this aliased but still descriptive syntax: total_price = N.mult(N.add(price, fee), vat)

Because Numbers dispatches based on protocol definitions, you only need to swap what kind of arguments are used to change the type of the result.

Overloaded Operators

As explicit opt-in functionality, Numbers will add overloaded operators to your module, if you write use Numbers, overload_operators: true

This will alter a + b, a - b, a * b, a / b, -a and abs(a) to dispatch to the corresponding functions in the Numbers module.

Do note that these overloaded operator versions are not allowed in guard tests, which is why this functionality is only provided as an opt-in option to use when an algorithm would be too unreadable without it.

Examples:

Using built-in numbers:

iex> alias Numbers, as: N
iex> N.add(1, 2)
3
iex> N.mult(3,5)
15
iex> N.mult(1.5, 100)
150.0

Using Decimals: (requires the Decimal library.)

iex> alias Numbers, as: N
iex> d = Decimal.new(2)
iex> N.div(d, 10)
#Decimal<0.2>
iex> small_number = N.div(d, 1234)
#Decimal<0.001620745542949756888168557536>
iex> N.pow(small_number, 100)
#Decimal<9.364478495445313580679473524E-280>

Defining your own Numbers implementations

See Numbers.Protocols for a full explanation on how to do this.

Link to this section Summary

Functions

The absolute value of a number.

Adds two Numeric a and b together.

Divides the Numeric a by b.

Unary minus. Returns the negation of the number.

Multiplies the Numeric a with the Numeric b

Power function: computes base^exponent, where base is Numeric, and exponent has to be an integer.

Subtracts the Numeric b from the Numeric a.

Convert the custom Numeric struct to the built-in float datatype.

Link to this section Types

Specs

t() :: any()

Link to this section Functions

Specs

abs(t()) :: t()

The absolute value of a number.

Depends on an implementation existing of Numbers.Protocols.Absolute

Specs

add(t(), t()) :: t()

Adds two Numeric a and b together.

Depends on an implementation existing of Numbers.Protocol.Addition

See Numbers.Protocols.Addition.add_id/1.

Specs

div(t(), t()) :: t()

Divides the Numeric a by b.

Note that this is a supposed to be a full (non-truncated) division; no rounding or truncation is supposed to happen, even when calculating with integers.

Depends on an implementation existing of Numbers.Protocol.Division

Specs

minus(t()) :: t()

Unary minus. Returns the negation of the number.

Depends on an implementation existing of Numbers.Protocols.Minus

Specs

mult(t(), t()) :: t()

Multiplies the Numeric a with the Numeric b

Depends on an implementation existing of Numbers.Protocol.Multiplication

See Numbers.Protocols.Multiplication.mult_id/1.

Link to this function

pow(num, power)

Specs

pow(t(), non_neg_integer()) :: t()

Power function: computes base^exponent, where base is Numeric, and exponent has to be an integer.

(This means that it is impossible to calculate roots by using this function.)

Depends on an implementation existing of Numbers.Protocol.Exponentiation

Specs

sub(t(), t()) :: t()

Subtracts the Numeric b from the Numeric a.

Depends on an implementation existing of Numbers.Protocol.Subtraction

Specs

to_float(t()) :: {:ok, t_as_float :: float()} | :error

Convert the custom Numeric struct to the built-in float datatype.

This operation might be lossy, losing precision in the process.