Skip to content

Commit 51e25fb

Browse files
Add Integer.ceil_div function (#14913)
1 parent cf454cd commit 51e25fb

File tree

2 files changed

+57
-0
lines changed

2 files changed

+57
-0
lines changed

lib/elixir/lib/integer.ex

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,35 @@ defmodule Integer do
172172
end
173173
end
174174

175+
@doc """
176+
Performs a ceiled integer division.
177+
178+
Raises an `ArithmeticError` exception if one of the arguments is not an
179+
integer, or when the `divisor` is `0`.
180+
181+
This function performs a *ceiled* integer division, which means that
182+
the result will always be rounded towards positive infinity.
183+
184+
## Examples
185+
186+
iex> Integer.ceil_div(5, 2)
187+
3
188+
iex> Integer.ceil_div(6, -4)
189+
-1
190+
iex> Integer.ceil_div(-99, 2)
191+
-49
192+
193+
"""
194+
@doc since: "1.20.0"
195+
@spec ceil_div(integer, neg_integer | pos_integer) :: integer
196+
def ceil_div(dividend, divisor) do
197+
if not :erlang.xor(dividend < 0, divisor < 0) and rem(dividend, divisor) != 0 do
198+
div(dividend, divisor) + 1
199+
else
200+
div(dividend, divisor)
201+
end
202+
end
203+
175204
@doc """
176205
Returns the ordered digits for the given `integer`.
177206

lib/elixir/test/elixir/integer_test.exs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,14 @@ defmodule IntegerTest do
4444
end
4545

4646
test "mod/2" do
47+
assert Integer.mod(10, -5) == 0
4748
assert Integer.mod(3, 2) == 1
4849
assert Integer.mod(0, 10) == 0
50+
assert Integer.mod(0, -5) == 0
4951
assert Integer.mod(30000, 2001) == 1986
52+
assert Integer.mod(30000, -2001) == -15
5053
assert Integer.mod(-20, 11) == 2
54+
assert Integer.mod(-55, -22) == -11
5155
end
5256

5357
test "mod/2 raises ArithmeticError when divisor is 0" do
@@ -56,10 +60,14 @@ defmodule IntegerTest do
5660
end
5761

5862
test "floor_div/2" do
63+
assert Integer.floor_div(10, -5) == -2
5964
assert Integer.floor_div(3, 2) == 1
6065
assert Integer.floor_div(0, 10) == 0
66+
assert Integer.floor_div(0, -5) == 0
6167
assert Integer.floor_div(30000, 2001) == 14
68+
assert Integer.floor_div(30000, -2001) == -15
6269
assert Integer.floor_div(-20, 11) == -2
70+
assert Integer.floor_div(-55, -22) == 2
6371
end
6472

6573
test "floor_div/2 raises ArithmeticError when divisor is 0" do
@@ -72,6 +80,26 @@ defmodule IntegerTest do
7280
assert_raise ArithmeticError, fn -> Integer.floor_div(20, 1.2) end
7381
end
7482

83+
test "ceil_div/2" do
84+
assert Integer.ceil_div(10, -5) == -2
85+
assert Integer.ceil_div(3, 2) == 2
86+
assert Integer.ceil_div(0, 10) == 0
87+
assert Integer.ceil_div(0, -10) == 0
88+
assert Integer.ceil_div(30000, -2001) == -14
89+
assert Integer.ceil_div(-20, 11) == -1
90+
assert Integer.ceil_div(-55, -22) == 3
91+
end
92+
93+
test "ceil_div/2 raises ArithmeticError when divisor is 0" do
94+
assert_raise ArithmeticError, fn -> Integer.ceil_div(3, 0) end
95+
assert_raise ArithmeticError, fn -> Integer.ceil_div(-50, 0) end
96+
end
97+
98+
test "ceil_div/2 raises ArithmeticError when non-integers used as arguments" do
99+
assert_raise ArithmeticError, fn -> Integer.ceil_div(3.0, 2) end
100+
assert_raise ArithmeticError, fn -> Integer.ceil_div(20, 1.2) end
101+
end
102+
75103
test "digits/2" do
76104
assert Integer.digits(0) == [0]
77105
assert Integer.digits(0, 2) == [0]

0 commit comments

Comments
 (0)