Numbers
Numbers is a tiny Elixir package that facilitates the creation of libraries that want to be able to use any kind of Numeric type.
Some known custom numeric types that implement the Numeric behaviour:
- Ratio -- rational numbers.
- Decimal -- arbitrary precision decimal numbers.
- Tensor -- Vectors, Matrices and higher-order tensors.
- ComplexNum -- Complex numbers.
How does it work?
This is done by writing a Behaviour called Numeric, which standardizes the names of the following common mathematical operations:
newto create a new number of the custom type from a basic integer or float (which be an operation that loses precision).addfor addition.subfor subtraction.mulfor multiplication.divfor division.minusfor unary minus (also known as negation).absfor taking the absolute value.pow(optional) for calculating integer powers. When no custom algorithm is specified by the data type, Numbers will provide a (possibly slower) variant itself using the Exponentiation by Squaring algorithm.to_float(optional) For some Numeric data types it is possible to convert it back to a built-in datatype (possibly losing precision in the process).
The Numbers module then dispatches these functions to YourStructModule when called with a %YourStructModule{} struct as one or both of its arguments.
If the other argument is a Float or Integer, then it is first converted to an instance of YourStruct by calling YourStructModule.new(the_int_or_float) on 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> 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)
Installation
The package can be installed as:
- Add
numbersto your list of dependencies inmix.exs:
```elixir
def deps do
[{:numbers, "~> 3.0.0"}]
end
```
Coercion
Version 3.0.0 introduces a new feature: Coercion between data types.
This allows for conversion of one datatype into an equivalent in another data type,
without being ambiguous. Check the documentation of Numeric/coerce/2 for details. :-).
Changelog
- 3.0.1 Improved README
- 3.0.0 Remove public
Numbers.coerce/2function, as it had confused naming and very limited use. Added optionalNumeric.coerce/2callback (which works very different from the oldNumbers.coerce/2function) which is now used underwater when coercion should happen. - 2.0.3 Improving documentation.
- 2.0.2 Adding many tests.
- 2.0.1 Fixing error message that is shown when conversion to float is not possible to use the Inspect protocol.
- 2.0.0 Breaking change,
mul->mult. - 1.0.0 First Stable Version.