Skip to content

Commit

Permalink
Fix detection of NaN in median() (#73)
Browse files Browse the repository at this point in the history
There is no reliable way to know only from the array eltype whether entries
support `isnan` or not. Better leave to the compiler to optimize out the
`isa Number` check when possible.
  • Loading branch information
nalimilan authored Mar 24, 2021
1 parent 55d93f7 commit ba24318
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/Statistics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -805,7 +805,7 @@ Like [`median`](@ref), but may overwrite the input vector.
function median!(v::AbstractVector)
isempty(v) && throw(ArgumentError("median of an empty array is undefined, $(repr(v))"))
eltype(v)>:Missing && any(ismissing, v) && return missing
(eltype(v)<:AbstractFloat || eltype(v)>:AbstractFloat) && any(isnan, v) && return convert(eltype(v), NaN)
any(x -> x isa Number && isnan(x), v) && return convert(eltype(v), NaN)
inds = axes(v, 1)
n = length(inds)
mid = div(first(inds)+last(inds),2)
Expand Down
9 changes: 9 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,15 @@ end
@test @inferred(median(Float16[1, 2, 3])) === Float16(2)
@test @inferred(median(Float32[1, 2, NaN])) === NaN32
@test @inferred(median(Float32[1, 2, 3])) === 2.0f0

# custom type implementing minimal interface
struct A
x
end
Statistics.middle(x::A, y::A) = A(middle(x.x, y.x))
Base.isless(x::A, y::A) = isless(x.x, y.x)
@test median([A(1), A(2)]) === A(1.5)
@test median(Any[A(1), A(2)]) === A(1.5)
end

@testset "mean" begin
Expand Down

0 comments on commit ba24318

Please sign in to comment.