diff --git a/base/range.jl b/base/range.jl index 5c7c043a4f85e..ea67d266cdd82 100644 --- a/base/range.jl +++ b/base/range.jl @@ -577,20 +577,35 @@ maximum(r::AbstractUnitRange) = isempty(r) ? throw(ArgumentError("range must be minimum(r::AbstractRange) = isempty(r) ? throw(ArgumentError("range must be non-empty")) : min(first(r), last(r)) maximum(r::AbstractRange) = isempty(r) ? throw(ArgumentError("range must be non-empty")) : max(first(r), last(r)) +""" + argmin(r::AbstractRange) + +Ranges can have multiple minimal elements. In that case +`argmin` will return a minimal index, but not necessarily the +first one. +""" function argmin(r::AbstractRange) if isempty(r) throw(ArgumentError("range must be non-empty")) elseif step(r) > 0 firstindex(r) else - lastindex(r) + first(searchsorted(r, last(r))) end end + +""" + argmax(r::AbstractRange) + +Ranges can have multiple maximal elements. In that case +`argmax` will return a maximal index, but not necessarily the +first one. +""" function argmax(r::AbstractRange) if isempty(r) throw(ArgumentError("range must be non-empty")) elseif step(r) > 0 - lastindex(r) + first(searchsorted(r, last(r))) else firstindex(r) end diff --git a/test/ranges.jl b/test/ranges.jl index eb5239aba378d..8f726a09565dd 100644 --- a/test/ranges.jl +++ b/test/ranges.jl @@ -1213,6 +1213,10 @@ end @test imax === argmax(r) @test extrema(r) === (r[imin], r[imax]) end + + r = 1f8-10:1f8 + @test_broken argmin(f) == argmin(collect(r)) + @test_broken argmax(f) == argmax(collect(r)) end @testset "OneTo" begin diff --git a/test/sorting.jl b/test/sorting.jl index 4559deddd3fd0..aa7b8f4386eaf 100644 --- a/test/sorting.jl +++ b/test/sorting.jl @@ -173,6 +173,11 @@ end end end + @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) + end end end # exercise the codepath in searchsorted* methods for ranges that check for zero step range