Skip to content

Commit 38c6077

Browse files
committed
Add Float.round function
Float.round allows rounding floats to arbitrary precision, as well as specifying how midpoint rounding is performed (up/down).
1 parent 3776623 commit 38c6077

File tree

2 files changed

+38
-0
lines changed

2 files changed

+38
-0
lines changed

lib/elixir/lib/float.ex

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,4 +125,29 @@ defmodule Float do
125125
end
126126
end
127127

128+
@doc """
129+
Rounds a floating point value to an arbitrary number of fractional digits
130+
(between 0 and 15) with an optional midpoint rounding mode (:up or :down,
131+
defaults to :up).
132+
133+
## Examples
134+
135+
iex> Float.round(5.5675, 3)
136+
5.568
137+
iex> Float.round(5.5675, 3, :down)
138+
5.567
139+
iex> Float.round(-5.5675, 3)
140+
-5.567
141+
iex> Float.round(-5.5675, 3, :down)
142+
-5.568
143+
"""
144+
@spec round(float, integer, atom | nil) :: float
145+
def round(number, precision, midpoint_rounding // :up) when is_float(number) and is_integer(precision) and precision in 0..15 do
146+
# Default to :up if anything but :down is provided for midpoint rounding mode
147+
case midpoint_rounding do
148+
:down -> Kernel.round(Float.floor(number * :math.pow(10, precision))) / :math.pow(10, precision)
149+
_ -> Kernel.round(Float.ceil(number * :math.pow(10, precision))) / :math.pow(10, precision)
150+
end
151+
end
152+
128153
end

lib/elixir/test/elixir/float_test.exs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,17 @@ defmodule FloatTest do
5757
assert Float.ceil(-0.32453e-10) === 0
5858
assert Float.ceil(1.32453e-10) === 1
5959
end
60+
61+
test :round do
62+
assert Float.round(5.5675, 3) === 5.568
63+
assert Float.round(5.5675, 3, :down) === 5.567
64+
assert Float.round(5.5, 3) === 5.5
65+
assert Float.round(5.5e-10, 10) === 6.0e-10
66+
assert Float.round(5.5e-10, 10, :down) === 5.0e-10
67+
assert Float.round(5.5e-10, 8) === 1.0e-8
68+
assert Float.round(5.5e-10, 8, :down) === 0.0
69+
assert Float.round(5.0, 0) === 5.0
70+
assert Float.round(-1.3456, 3) === -1.345
71+
assert Float.round(-1.3456, 3, :down) === -1.346
72+
end
6073
end

0 commit comments

Comments
 (0)