diff --git a/lib/elixir/lib/float.ex b/lib/elixir/lib/float.ex index 325fb7c6e3e..5bbf4a817a3 100644 --- a/lib/elixir/lib/float.ex +++ b/lib/elixir/lib/float.ex @@ -80,4 +80,49 @@ defmodule Float do result end end + + @doc """ + Round a float to the largest integer less than or equal to `num` + + ## Examples + iex> Float.floor(34) + 34 + iex> Float.floor(34.25) + 34 + iex> Float.floor(-56.5) + -57 + + """ + @spec floor(float | integer) :: integer + def floor(num) when is_integer(num), do: num + def floor(num) when is_float(num) do + truncated = :erlang.trunc(num) + case :erlang.abs(num - truncated) do + x when x > 0 and num < 0 -> truncated - 1 + x -> truncated + end + end + + @doc """ + Round a float to the largest integer greater than or equal to `num` + + ## Examples + iex> Float.ceil(34) + 34 + iex> Float.ceil(34.25) + 35 + iex> Float.ceil(-56.5) + -56 + + """ + @spec ceil(float | integer) :: integer + def ceil(num) when is_integer(num), do: num + def ceil(num) when is_float(num) do + truncated = :erlang.trunc(num) + case :erlang.abs(num - truncated) do + x when x > 0 and num > 0 -> truncated + 1 + x -> truncated + end + end + end diff --git a/lib/elixir/test/elixir/float_test.exs b/lib/elixir/test/elixir/float_test.exs index 53652f7dd15..8d100757284 100644 --- a/lib/elixir/test/elixir/float_test.exs +++ b/lib/elixir/test/elixir/float_test.exs @@ -25,4 +25,36 @@ defmodule FloatTest do assert Float.parse("++1.2") === :error assert Float.parse("pi") === :error end + + test :floor do + assert Float.floor(12) === 12 + assert Float.floor(-12) === -12 + assert Float.floor(12.524235) === 12 + assert Float.floor(-12.5) === -13 + assert Float.floor(-12.524235) === -13 + assert Float.floor(7.5e3) === 7500 + assert Float.floor(7.5432e3) === 7543 + assert Float.floor(7.5e-3) === 0 + assert Float.floor(-12.32453e4) === -123246 + assert Float.floor(-12.32453e-10) === -1 + assert Float.floor(0.32453e-10) === 0 + assert Float.floor(-0.32453e-10) === -1 + assert Float.floor(1.32453e-10) === 0 + end + + test :ceil do + assert Float.ceil(12) === 12 + assert Float.ceil(-12) === -12 + assert Float.ceil(12.524235) === 13 + assert Float.ceil(-12.5) === -12 + assert Float.ceil(-12.524235) === -12 + assert Float.ceil(7.5e3) === 7500 + assert Float.ceil(7.5432e3) === 7544 + assert Float.ceil(7.5e-3) === 1 + assert Float.ceil(-12.32453e4) === -123245 + assert Float.ceil(-12.32453e-10) === 0 + assert Float.ceil(0.32453e-10) === 1 + assert Float.ceil(-0.32453e-10) === 0 + assert Float.ceil(1.32453e-10) === 1 + end end