Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
29 changes: 29 additions & 0 deletions lib/elixir/lib/integer.ex
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,35 @@ defmodule Integer do
end
end

@doc """
Performs a ceiled integer division.

Raises an `ArithmeticError` exception if one of the arguments is not an
integer, or when the `divisor` is `0`.

This function performs a *ceiled* integer division, which means that
the result will always be rounded towards positive infinity.

## Examples

iex> Integer.ceil_div(5, 2)
3
iex> Integer.ceil_div(6, -4)
-1
iex> Integer.ceil_div(-99, 2)
-49

"""
@doc since: "1.20.0"
@spec ceil_div(integer, neg_integer | pos_integer) :: integer
def ceil_div(dividend, divisor) do
if not :erlang.xor(dividend < 0, divisor < 0) and rem(dividend, divisor) != 0 do
div(dividend, divisor) + 1
else
div(dividend, divisor)
end
end

@doc """
Returns the ordered digits for the given `integer`.

Expand Down
30 changes: 28 additions & 2 deletions lib/elixir/test/elixir/integer_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,13 @@ defmodule IntegerTest do
end

test "mod/2" do
assert Integer.mod(10, -5) == 0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(nit) the ordering of this case feels weird, would keep it after the positive args

assert Integer.mod(3, 2) == 1
assert Integer.mod(0, 10) == 0
assert Integer.mod(30000, 2001) == 1986
assert Integer.mod(0, -5) == 0
assert Integer.mod(30000, -2001) == -15
assert Integer.mod(-20, 11) == 2
assert Integer.mod(-55, -22) == -11
end

test "mod/2 raises ArithmeticError when divisor is 0" do
Expand All @@ -56,10 +59,13 @@ defmodule IntegerTest do
end

test "floor_div/2" do
assert Integer.floor_div(10, -5) == -2
assert Integer.floor_div(3, 2) == 1
assert Integer.floor_div(0, 10) == 0
assert Integer.floor_div(30000, 2001) == 14
assert Integer.floor_div(0, -5) == 0
assert Integer.floor_div(30000, -2001) == -15
assert Integer.floor_div(-20, 11) == -2
assert Integer.floor_div(-55, -22) == 2
end

test "floor_div/2 raises ArithmeticError when divisor is 0" do
Expand All @@ -72,6 +78,26 @@ defmodule IntegerTest do
assert_raise ArithmeticError, fn -> Integer.floor_div(20, 1.2) end
end

test "ceil_div/2" do
assert Integer.ceil_div(10, -5) == -2
assert Integer.ceil_div(3, 2) == 2
assert Integer.ceil_div(0, 10) == 0
assert Integer.ceil_div(0, -10) == 0
assert Integer.ceil_div(30000, -2001) == -14
assert Integer.ceil_div(-20, 11) == -1
assert Integer.ceil_div(-55, -22) == 3
end

test "ceil_div/2 raises ArithmeticError when divisor is 0" do
assert_raise ArithmeticError, fn -> Integer.ceil_div(3, 0) end
assert_raise ArithmeticError, fn -> Integer.ceil_div(-50, 0) end
end

test "ceil_div/2 raises ArithmeticError when non-integers used as arguments" do
assert_raise ArithmeticError, fn -> Integer.ceil_div(3.0, 2) end
assert_raise ArithmeticError, fn -> Integer.ceil_div(20, 1.2) end
end

test "digits/2" do
assert Integer.digits(0) == [0]
assert Integer.digits(0, 2) == [0]
Expand Down