Skip to content

Commit 6a63e29

Browse files
jw3126KristofferC
authored andcommitted
fix #34157, searchsorted corner case (e.g. searching for Inf) (#34224)
1 parent 12e83af commit 6a63e29

File tree

2 files changed

+58
-4
lines changed

2 files changed

+58
-4
lines changed

base/sort.jl

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -250,19 +250,37 @@ end
250250

251251
function searchsortedlast(a::AbstractRange{<:Integer}, x::Real, o::DirectOrdering)
252252
require_one_based_indexing(a)
253-
if step(a) == 0
253+
h = step(a)
254+
if h == 0
254255
lt(o, x, first(a)) ? 0 : length(a)
256+
elseif h > 0 && x < first(a)
257+
firstindex(a) - 1
258+
elseif h > 0 && x >= last(a)
259+
lastindex(a)
260+
elseif h < 0 && x > first(a)
261+
firstindex(a) - 1
262+
elseif h < 0 && x <= last(a)
263+
lastindex(a)
255264
else
256-
clamp( fld(floor(Integer, x) - first(a), step(a)) + 1, 0, length(a))
265+
fld(floor(Integer, x) - first(a), h) + 1
257266
end
258267
end
259268

260269
function searchsortedfirst(a::AbstractRange{<:Integer}, x::Real, o::DirectOrdering)
261270
require_one_based_indexing(a)
262-
if step(a) == 0
271+
h = step(a)
272+
if h == 0
263273
lt(o, first(a), x) ? length(a)+1 : 1
274+
elseif h > 0 && x <= first(a)
275+
firstindex(a)
276+
elseif h > 0 && x > last(a)
277+
lastindex(a) + 1
278+
elseif h < 0 && x >= first(a)
279+
firstindex(a)
280+
elseif h < 0 && x < last(a)
281+
lastindex(a) + 1
264282
else
265-
clamp(-fld(floor(Integer, -x) + first(a), step(a)) + 1, 1, length(a) + 1)
283+
-fld(floor(Integer, -x) + first(a), h) + 1
266284
end
267285
end
268286

test/sorting.jl

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,42 @@ end
138138
@test searchsortedlast(500:1.0:600, -1.0e20) == 0
139139
@test searchsortedlast(500:1.0:600, 1.0e20) == 101
140140
end
141+
@testset "issue #34157" begin
142+
@test searchsorted(1:2.0, -Inf) === 1:0
143+
@test searchsorted([1,2], -Inf) === 1:0
144+
@test searchsorted(1:2, -Inf) === 1:0
145+
146+
@test searchsorted(1:2.0, Inf) === 3:2
147+
@test searchsorted([1,2], Inf) === 3:2
148+
@test searchsorted(1:2, Inf) === 3:2
149+
150+
for coll in [
151+
Base.OneTo(10),
152+
1:2,
153+
-4:6,
154+
5:2:10,
155+
[1,2],
156+
1.0:4,
157+
[10.0,20.0],
158+
]
159+
for huge in [Inf, 1e300]
160+
@test searchsortedfirst(coll, huge) === lastindex(coll) + 1
161+
@test searchsortedfirst(coll, -huge)=== firstindex(coll)
162+
@test searchsortedlast(coll, huge) === lastindex(coll)
163+
@test searchsortedlast(coll, -huge) === firstindex(coll) - 1
164+
@test searchsorted(coll, huge) === lastindex(coll)+1 : lastindex(coll)
165+
@test searchsorted(coll, -huge) === firstindex(coll) : firstindex(coll) - 1
166+
167+
@test searchsortedfirst(reverse(coll), huge, rev=true) === firstindex(coll)
168+
@test searchsortedfirst(reverse(coll), -huge, rev=true) === lastindex(coll) + 1
169+
@test searchsortedlast(reverse(coll), huge, rev=true) === firstindex(coll) - 1
170+
@test searchsortedlast(reverse(coll), -huge, rev=true) === lastindex(coll)
171+
@test searchsorted(reverse(coll), huge, rev=true) === firstindex(coll):firstindex(coll) - 1
172+
@test searchsorted(reverse(coll), -huge, rev=true) === lastindex(coll)+1:lastindex(coll)
173+
174+
end
175+
end
176+
end
141177
end
142178
# exercise the codepath in searchsorted* methods for ranges that check for zero step range
143179
struct ConstantRange{T} <: AbstractRange{T}

0 commit comments

Comments
 (0)