diff --git a/lib/elixir/lib/range.ex b/lib/elixir/lib/range.ex index 759d21b2f9..50b1680985 100644 --- a/lib/elixir/lib/range.ex +++ b/lib/elixir/lib/range.ex @@ -258,7 +258,7 @@ defmodule Range do def size(range) def size(first..last//step) when step > 0 and first > last, do: 0 def size(first..last//step) when step < 0 and first < last, do: 0 - def size(first..last//step), do: abs(div(last - first, step)) + 1 + def size(first..last//step), do: div(last - first, step) + 1 # TODO: Remove me on v2.0 def size(%{__struct__: Range, first: first, last: last} = range) do @@ -487,7 +487,7 @@ defmodule Range do last2 < first1 or last1 < first2 -> true - abs(step1) == 1 and abs(step2) == 1 -> + step1 == 1 and step2 == 1 -> false true -> @@ -522,7 +522,7 @@ defmodule Range do end defp normalize(first, last, step) when first > last, - do: {first - abs(div(first - last, step) * step), first, -step} + do: {first - div(first - last, step) * step, first, -step} # A single-element range holds the same element regardless of the step, so # make the step positive to keep the progression in disjoint?/2 increasing. diff --git a/lib/elixir/test/elixir/range_test.exs b/lib/elixir/test/elixir/range_test.exs index 6ffc68482f..8ce051f330 100644 --- a/lib/elixir/test/elixir/range_test.exs +++ b/lib/elixir/test/elixir/range_test.exs @@ -65,6 +65,10 @@ defmodule RangeTest do assert Range.shift(10..0//-2, -2) == 14..4//-2 end + test "size of a single-element range with a negative step" do + assert Range.size(1..1//-4) == 1 + end + test "in guard equality" do case {1, 1..1} do {n, range} when range == n..n//1 -> true @@ -117,6 +121,10 @@ defmodule RangeTest do assert Range.disjoint?(3..3//-3, 1..5) == false assert Range.disjoint?(1..5, 3..3//-3) == false end + + test "normalizes unaligned descending ranges to their actual bounds" do + refute Range.disjoint?(27..11//-3, 26..0//-5) + end end describe "split" do