Skip to content

Commit

Permalink
Return special floats as atoms, not nils
Browse files Browse the repository at this point in the history
  • Loading branch information
versilov committed May 13, 2018
1 parent fe72276 commit 5c19608
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 23 deletions.
33 changes: 14 additions & 19 deletions lib/matrex.ex
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ defmodule Matrex do
## NaN and Infinity
Float special values, like `NaN` and `Inf` live well inside matrices.
But when getting them into Elixir they are transferred to `nil` values,
But when getting them into Elixir they are transferred to `Nan`,`Inf` and `NegInf` atoms,
because BEAM does not accept special values as valid floats.
iex> m = Matrex.eye(3)
Expand All @@ -54,14 +54,20 @@ defmodule Matrex do
│ 0.0 0.0 1.0 │
└ ┘
iex> Matrex.divide(m, Matrex.zeros(3))
iex> n = Matrex.divide(m, Matrex.zeros(3))
#Matrex[3×3]
┌ ┐
│ ∞ NaN NaN │
│ NaN ∞ NaN │
│ NaN NaN ∞ │
└ ┘
iex> n[1][1]
Inf
iex> n[1][2]
NaN
"""

alias Matrex.NIFs
Expand Down Expand Up @@ -597,9 +603,9 @@ defmodule Matrex do
end

@spec binary_to_float(<<_::32>>) :: element | nil
defp binary_to_float(@not_a_number), do: nil
defp binary_to_float(@positive_infinity), do: nil
defp binary_to_float(@negative_infinity), do: nil
defp binary_to_float(@not_a_number), do: NaN
defp binary_to_float(@positive_infinity), do: Inf
defp binary_to_float(@negative_infinity), do: NegInf
defp binary_to_float(<<val::float-little-32>>), do: val

@doc """
Expand Down Expand Up @@ -851,27 +857,16 @@ defmodule Matrex do
6.0
"""
@spec first(matrex) :: element | nil
def first(%Matrex{
data: <<
_rows::unsigned-integer-little-32,
_columns::unsigned-integer-little-32,
specl_float::binary-size(4),
_rest::binary
>>
})
when specl_float in [@not_a_number, @positive_infinity, @negative_infinity],
do: nil

@spec first(matrex) :: element | NaN | Inf | NegInf
def first(%Matrex{
data: <<
_rows::unsigned-integer-little-32,
_columns::unsigned-integer-little-32,
element::float-little-32,
element::binary-4,
_rest::binary
>>
}),
do: element
do: binary_to_float(element)

@doc """
Displays a visualization of the matrix.
Expand Down
8 changes: 4 additions & 4 deletions lib/matrex/inspect.ex
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ defmodule Matrex.Inspect do
defp format_row(%Matrex{} = matrex, row, _rows, columns, suffix_size, prefix_size)
when suffix_size + prefix_size >= columns do
matrex
|> Matrex.row_to_list(row)
|> row_to_list_of_binaries(row)
|> Enum.map(&format_float(&1))
|> Enum.join()
end
Expand Down Expand Up @@ -136,13 +136,13 @@ defmodule Matrex.Inspect do

defp format_row_head_tail(<<>>, _, _), do: <<>>

defp format_row_head_tail(<<val::float-little-32, rest::binary>>, 1, prefix_size)
defp format_row_head_tail(<<val::binary-4, rest::binary>>, 1, prefix_size)
when prefix_size > 0 do
<<format_float(val) <> IO.ANSI.white() <> " │\n│" <> IO.ANSI.yellow(),
format_row_head_tail(rest, 0, prefix_size)::binary>>
end

defp format_row_head_tail(<<val::float-little-32, rest::binary>>, 0, prefix_size)
defp format_row_head_tail(<<val::binary-4, rest::binary>>, 0, prefix_size)
when prefix_size > 0 do
<<
format_float(val)::binary,
Expand All @@ -151,7 +151,7 @@ defmodule Matrex.Inspect do
>>
end

defp format_row_head_tail(<<val::float-little-32, rest::binary>>, suffix_size, prefix_size)
defp format_row_head_tail(<<val::binary-4, rest::binary>>, suffix_size, prefix_size)
when suffix_size > 0 do
<<format_float(val)::binary,
format_row_head_tail(rest, suffix_size - 1, prefix_size)::binary>>
Expand Down

0 comments on commit 5c19608

Please sign in to comment.