Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions lib/elixir/lib/float.ex
Original file line number Diff line number Diff line change
Expand Up @@ -125,4 +125,29 @@ defmodule Float do
end
end

@doc """
Rounds a floating point value to an arbitrary number of fractional digits
(between 0 and 15) with an optional midpoint rounding mode (:up or :down,
defaults to :up).

## Examples

iex> Float.round(5.5675, 3)
5.568
iex> Float.round(5.5675, 3, :down)
5.567
iex> Float.round(-5.5675, 3)
-5.567
iex> Float.round(-5.5675, 3, :down)
-5.568
"""
@spec round(float, integer, atom | nil) :: float
def round(number, precision, midpoint_rounding // :up) when is_float(number) and is_integer(precision) and precision in 0..15 do
# Default to :up if anything but :down is provided for midpoint rounding mode
case midpoint_rounding do
:down -> Kernel.round(Float.floor(number * :math.pow(10, precision))) / :math.pow(10, precision)
_ -> Kernel.round(Float.ceil(number * :math.pow(10, precision))) / :math.pow(10, precision)
end
end

end
13 changes: 13 additions & 0 deletions lib/elixir/test/elixir/float_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,17 @@ defmodule FloatTest do
assert Float.ceil(-0.32453e-10) === 0
assert Float.ceil(1.32453e-10) === 1
end

test :round do
assert Float.round(5.5675, 3) === 5.568
assert Float.round(5.5675, 3, :down) === 5.567
assert Float.round(5.5, 3) === 5.5
assert Float.round(5.5e-10, 10) === 6.0e-10
assert Float.round(5.5e-10, 10, :down) === 5.0e-10
assert Float.round(5.5e-10, 8) === 1.0e-8
assert Float.round(5.5e-10, 8, :down) === 0.0
assert Float.round(5.0, 0) === 5.0
assert Float.round(-1.3456, 3) === -1.345
assert Float.round(-1.3456, 3, :down) === -1.346
end
end