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
4 changes: 2 additions & 2 deletions base/range.jl
Original file line number Diff line number Diff line change
Expand Up @@ -705,7 +705,7 @@ function argmin(r::AbstractRange)
elseif step(r) > 0
firstindex(r)
else
first(searchsorted(r, last(r)))
lastindex(r)
end
end

Expand All @@ -720,7 +720,7 @@ function argmax(r::AbstractRange)
if isempty(r)
throw(ArgumentError("range must be non-empty"))
elseif step(r) > 0
first(searchsorted(r, last(r)))
lastindex(r)
else
firstindex(r)
end
Expand Down
82 changes: 26 additions & 56 deletions base/sort.jl
Original file line number Diff line number Diff line change
Expand Up @@ -231,92 +231,62 @@ end

function searchsortedlast(a::AbstractRange{<:Real}, x::Real, o::DirectOrdering)::keytype(a)
require_one_based_indexing(a)
if step(a) == 0
lt(o, x, first(a)) ? 0 : length(a)
f, h, l = first(a), step(a), last(a)
if lt(o, x, f)
0
elseif h == 0 || !lt(o, x, l)
length(a)
else
n = round(Integer, clamp((x - first(a)) / step(a) + 1, 1, length(a)))
n = round(Integer, (x - f) / h + 1)
lt(o, x, a[n]) ? n - 1 : n
end
end

function searchsortedfirst(a::AbstractRange{<:Real}, x::Real, o::DirectOrdering)::keytype(a)
require_one_based_indexing(a)
if step(a) == 0
lt(o, first(a), x) ? length(a) + 1 : 1
f, h, l = first(a), step(a), last(a)
if !lt(o, f, x)
1
elseif h == 0 || lt(o, l, x)
length(a) + 1
else
n = round(Integer, clamp((x - first(a)) / step(a) + 1, 1, length(a)))
n = round(Integer, (x - f) / h + 1)
lt(o, a[n], x) ? n + 1 : n
end
end

function searchsortedlast(a::AbstractRange{<:Integer}, x::Real, o::DirectOrdering)::keytype(a)
require_one_based_indexing(a)
h = step(a)
if h == 0
lt(o, x, first(a)) ? 0 : length(a)
elseif h > 0 && x < first(a)
firstindex(a) - 1
elseif h > 0 && x >= last(a)
lastindex(a)
elseif h < 0 && x > first(a)
firstindex(a) - 1
elseif h < 0 && x <= last(a)
lastindex(a)
f, h, l = first(a), step(a), last(a)
if lt(o, x, f)
0
elseif h == 0 || !lt(o, x, l)
length(a)
else
if o isa ForwardOrdering
fld(floor(Integer, x) - first(a), h) + 1
fld(floor(Integer, x) - f, h) + 1
else
fld(ceil(Integer, x) - first(a), h) + 1
fld(ceil(Integer, x) - f, h) + 1
end
end
end

function searchsortedfirst(a::AbstractRange{<:Integer}, x::Real, o::DirectOrdering)::keytype(a)
require_one_based_indexing(a)
h = step(a)
if h == 0
lt(o, first(a), x) ? length(a)+1 : 1
elseif h > 0 && x <= first(a)
firstindex(a)
elseif h > 0 && x > last(a)
lastindex(a) + 1
elseif h < 0 && x >= first(a)
firstindex(a)
elseif h < 0 && x < last(a)
lastindex(a) + 1
f, h, l = first(a), step(a), last(a)
if !lt(o, f, x)
1
elseif h == 0 || lt(o, l, x)
length(a) + 1
else
if o isa ForwardOrdering
-fld(floor(Integer, -x) + Signed(first(a)), h) + 1
cld(ceil(Integer, x) - f, h) + 1
else
-fld(ceil(Integer, -x) + Signed(first(a)), h) + 1
cld(floor(Integer, x) - f, h) + 1
end
end
end

function searchsortedfirst(a::AbstractRange{<:Integer}, x::Unsigned, o::DirectOrdering)::keytype(a)
require_one_based_indexing(a)
if lt(o, first(a), x)
if step(a) == 0
length(a) + 1
else
min(cld(x - first(a), step(a)), length(a)) + 1
end
else
1
end
end

function searchsortedlast(a::AbstractRange{<:Integer}, x::Unsigned, o::DirectOrdering)::keytype(a)
require_one_based_indexing(a)
if lt(o, x, first(a))
0
elseif step(a) == 0
length(a)
else
min(fld(x - first(a), step(a)) + 1, length(a))
end
end

searchsorted(a::AbstractRange{<:Real}, x::Real, o::DirectOrdering) =
searchsortedfirst(a, x, o) : searchsortedlast(a, x, o)

Expand Down
45 changes: 28 additions & 17 deletions test/sorting.jl
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ end
@test searchsorted(fill(R(1), 15), T(1), 6, 10, Forward) == 6:10
end

for (rg,I) in [(49:57,47:59), (1:2:17,-1:19), (-3:0.5:2,-5:.5:4)]
for (rg,I) in Any[(49:57,47:59), (1:2:17,-1:19), (-3:0.5:2,-5:.5:4)]
rg_r = reverse(rg)
rgv, rgv_r = [rg;], [rg_r;]
for i = I
Expand Down Expand Up @@ -144,7 +144,7 @@ end

@testset "issue 32568" begin
for R in numTypes, T in numTypes
for arr in [R[1:5;], R(1):R(5), R(1):2:R(5)]
for arr in Any[R[1:5;], R(1):R(5), R(1):2:R(5)]
@test eltype(searchsorted(arr, T(2))) == keytype(arr)
@test eltype(searchsorted(arr, T(2), big(1), big(4), Forward)) == keytype(arr)
@test searchsortedfirst(arr, T(2)) isa keytype(arr)
Expand All @@ -164,35 +164,46 @@ end
@test searchsorted([1,2], Inf) === 3:2
@test searchsorted(1:2, Inf) === 3:2

for coll in [
for coll in Any[
Base.OneTo(10),
1:2,
0x01:0x02,
-4:6,
5:2:10,
[1,2],
1.0:4,
[10.0,20.0],
]
for huge in [Inf, 1e300]
for huge in Any[Inf, 1e300, typemax(Int64), typemax(UInt64)]
@test searchsortedfirst(coll, huge) === lastindex(coll) + 1
@test searchsortedfirst(coll, -huge)=== firstindex(coll)
@test searchsortedlast(coll, huge) === lastindex(coll)
@test searchsortedlast(coll, -huge) === firstindex(coll) - 1
@test searchsorted(coll, huge) === lastindex(coll)+1 : lastindex(coll)
@test searchsorted(coll, -huge) === firstindex(coll) : firstindex(coll) - 1

@test searchsortedfirst(reverse(coll), huge, rev=true) === firstindex(coll)
@test searchsortedfirst(reverse(coll), -huge, rev=true) === lastindex(coll) + 1
@test searchsortedlast(reverse(coll), huge, rev=true) === firstindex(coll) - 1
@test searchsortedlast(reverse(coll), -huge, rev=true) === lastindex(coll)
@test searchsorted(reverse(coll), huge, rev=true) === firstindex(coll):firstindex(coll) - 1
@test searchsorted(reverse(coll), -huge, rev=true) === lastindex(coll)+1:lastindex(coll)
if !(eltype(coll) <: Unsigned)
@test searchsortedfirst(reverse(coll), huge, rev=true) === firstindex(coll)
@test searchsortedlast(reverse(coll), huge, rev=true) === firstindex(coll) - 1
@test searchsorted(reverse(coll), huge, rev=true) === firstindex(coll):firstindex(coll) - 1
end

if !(huge isa Unsigned)
@test searchsortedfirst(coll, -huge)=== firstindex(coll)
@test searchsortedlast(coll, -huge) === firstindex(coll) - 1
@test searchsorted(coll, -huge) === firstindex(coll) : firstindex(coll) - 1
if !(eltype(coll) <: Unsigned)
@test searchsortedfirst(reverse(coll), -huge, rev=true) === lastindex(coll) + 1
@test searchsortedlast(reverse(coll), -huge, rev=true) === lastindex(coll)
@test searchsorted(reverse(coll), -huge, rev=true) === lastindex(coll)+1:lastindex(coll)
end
end
end
end
@testset "issue ##34408" begin

@test_broken length(reverse(0x1:0x2)) == 2
@testset "issue #34408" begin
r = 1f8-10:1f8
# collect(r) = Float32[9.999999e7, 9.999999e7, 9.999999e7, 9.999999e7, 1.0e8, 1.0e8, 1.0e8, 1.0e8, 1.0e8]
@test_broken searchsorted(collect(r)) == searchsorted(r)
for i in r
@test_broken searchsorted(collect(r), i) == searchsorted(r, i)
end
end
end
@testset "issue #35272" begin
Expand Down Expand Up @@ -329,7 +340,7 @@ end
@test insorted(T(10), R.(collect(1:10)), by=(>=(5)))
end

for (rg,I) in [(49:57,47:59), (1:2:17,-1:19), (-3:0.5:2,-5:.5:4)]
for (rg,I) in Any[(49:57,47:59), (1:2:17,-1:19), (-3:0.5:2,-5:.5:4)]
rg_r = reverse(rg)
rgv, rgv_r = collect(rg), collect(rg_r)
for i = I
Expand Down