From b9f32379b0be96e3117566862991d516d8d5cb42 Mon Sep 17 00:00:00 2001 From: Chunji Wang Date: Thu, 31 Aug 2023 19:00:05 -0700 Subject: [PATCH 1/2] Prevent overflow in `mean(::AbstractRange)` and relax type constraint --- src/Statistics.jl | 6 +++--- test/runtests.jl | 12 ++++++++++-- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/Statistics.jl b/src/Statistics.jl index 64ba7560..74f325df 100644 --- a/src/Statistics.jl +++ b/src/Statistics.jl @@ -197,9 +197,9 @@ if !isdefined(Base, :mean) end end - function mean(r::AbstractRange{<:Real}) - isempty(r) && return oftype((first(r) + last(r)) / 2, NaN) - (first(r) + last(r)) / 2 + function mean(r::AbstractRange{T}) where T + isempty(r) && return zero(T) / 0 + return first(r) / 2 + last(r) / 2 end end diff --git a/test/runtests.jl b/test/runtests.jl index 6903f90b..8d8fbec4 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -194,8 +194,16 @@ end @test f(2:0.1:n) ≈ f([2:0.1:n;]) end end - @test mean(2:1) === NaN - @test mean(big(2):1) isa BigFloat + @test mean(2:0.1:4) === 3.0 # N.B. mean([2:0.1:4;]) != 3 + @test mean(LinRange(2im, 4im, 21)) === 3.0im + @test mean(2:1//10:4) === 3//1 + @test isnan(@inferred(mean(2:1))::Float64) + @test isnan(@inferred(mean(big(2):1))::BigFloat) + z = @inferred(mean(LinRange(2im, 1im, 0)))::ComplexF64 + @test isnan(real(z)) & isnan(imag(z)) + @test_throws DivideError mean(2//1:1) + @test mean(typemax(Int):typemax(Int)) === float(typemax(Int)) + @test mean(prevfloat(Inf):prevfloat(Inf)) === prevfloat(Inf) end @testset "var & std" begin From 9a31749b051c068590c1ad133a8b105861319ab8 Mon Sep 17 00:00:00 2001 From: Chunji Wang <7267426+chunjiw@users.noreply.github.com> Date: Sat, 9 Sep 2023 12:28:46 -0700 Subject: [PATCH 2/2] Make `mean(::AbstractRange)` fix more readable Co-authored-by: Milan Bouchet-Valat --- src/Statistics.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Statistics.jl b/src/Statistics.jl index 74f325df..6961feeb 100644 --- a/src/Statistics.jl +++ b/src/Statistics.jl @@ -198,8 +198,8 @@ if !isdefined(Base, :mean) end function mean(r::AbstractRange{T}) where T - isempty(r) && return zero(T) / 0 - return first(r) / 2 + last(r) / 2 + isempty(r) && return zero(T)/0 + return first(r)/2 + last(r)/2 end end