# Infinity in Elixir/Erlang?

I found there’s no builtin infinity, negative infinity and NaN in Elixir/Erlang. How do you solve this problem? I know I can use `:infinity` so that I can compare it and all numbers, but how about negative infinity and NaN?

2 Likes

There is neither. Even `:infinity` does only work by accident (term ordering).

1 Like

@tony612: as @NobbZ said there are no equivalents.

If you really need to have them then you need a small hack.

The reason we can compare different data types is pragmatism. Sorting algorithms don’t need to worry about different data types in order to sort. The overall sorting order is defined below:

`number < atom < reference < function < port < pid < tuple < map < list < bitstring`

Therefore you could use a hack like this one:

``````negative_infinity = {}
number = {0}
infinity = {:infinity}

negative_infinity < number
# true
number < infinity
# true
``````

I’m not sure, but I think that comparing numbers should be faster than comparing them in tuples, so personally I don’t recommend them. At least for me comparing tuples is less clear.

The Elixir-way is to pattern-match them:

``````defmodule MyComparator do
def compare(:infinity, :negative_infinity), do: :gt
def compare(:infinity, number) when is_number(number), do: :gt
def compare(:negative_infinity, :infinity), do: :lt
def compare(:negative_infinity, number) when is_number(number), do: :lt
def compare(number, :infinity) when is_number(number), do: :lt
def compare(number, :negative_infinity) when is_number(number), do: :gt

# def eq ...
# def ge ...
# def gt ...
# def le ...
# def lg ...
# def ne ...
end
``````

Similarly for NaN. In `JavaScript` expression: `0 / 0` returns `NaN`, but Elixir raises `ArithmeticError`.
From here you have two ways:

1. `try/rescue` - use this only you don’t have any other way
2. `pattern matching` - really recommend - it’s 100% Elixir-way
``````defmodule MyMath do
def safe_div(_dividend, 0), do: {:error, :dividing_by_zero}
def safe_div(dividend, divider), do: {:ok, dividend / divider}
end

# first_num = ...
# second_num = ...
case MyMath.safe_div(first_num, second_num) do
{:ok, _result} -> IO.puts "Yeah!"
{:error, _error} -> IO.puts "Oops!"
end
``````

Is it what you are looking for?

4 Likes