diff --git a/base/reduce.jl b/base/reduce.jl index 9041fd088ccf3..cb4e9f07a21d2 100644 --- a/base/reduce.jl +++ b/base/reduce.jl @@ -14,7 +14,7 @@ The reduction operator used in `sum`. The main difference from [`+`](@ref) is th integers are promoted to `Int`/`UInt`. """ add_sum(x, y) = x + y -add_sum(x::BitSignedSmall, y::BitSignedSmall) = Int(x) + Int(y) +add_sum(x::Union{Bool,BitIntegerSmall}, y::Union{Bool,BitIntegerSmall}) = Int(x) + Int(y) add_sum(x::BitUnsignedSmall, y::BitUnsignedSmall) = UInt(x) + UInt(y) add_sum(x::Real, y::Real)::Real = x + y @@ -1073,8 +1073,8 @@ julia> count(i->(4<=i<=6), [2,3,4,5,6]) julia> count([true, false, true, true]) 3 -julia> count(>(3), 1:7, init=0x03) -0x07 +julia> count(>(3), 1:7, init=UInt(0)) +0x0000000000000004 ``` """ count(itr; init=0) = count(identity, itr; init) @@ -1083,8 +1083,10 @@ count(f, itr; init=0) = _simple_count(f, itr, init) _simple_count(pred, itr, init) = sum(_bool(pred), itr; init) -function _simple_count(::typeof(identity), x::Array{Bool}, init::T=0) where {T} - n::T = init +function _simple_count(::typeof(identity), x::Array{Bool}, init=0) + v0 = Base.add_sum(init, false) + T = typeof(v0) + n::T = v0 chunks = length(x) ÷ sizeof(UInt) mask = 0x0101010101010101 % UInt GC.@preserve x begin diff --git a/test/reduce.jl b/test/reduce.jl index c6274711cdef4..7500b00197847 100644 --- a/test/reduce.jl +++ b/test/reduce.jl @@ -586,11 +586,11 @@ struct NonFunctionIsZero end @test count(NonFunctionIsZero(), [0]) == 1 @test count(NonFunctionIsZero(), [1]) == 0 -@test count(Iterators.repeated(true, 3), init=0x04) === 0x07 -@test count(!=(2), Iterators.take(1:7, 3), init=Int32(0)) === Int32(2) -@test count(identity, [true, false], init=Int8(5)) === Int8(6) -@test count(!, [true false; false true], dims=:, init=Int16(0)) === Int16(2) -@test isequal(count(identity, [true false; false true], dims=2, init=UInt(4)), reshape(UInt[5, 5], 2, 1)) +@test count(Iterators.repeated(true, 3), init=UInt(0)) === UInt(3) +@test count(!=(2), Iterators.take(1:7, 3), init=Int32(0)) === 2 +@test count(identity, [true, false], init=Int8(0)) === 1 +@test count(!, [true false; false true], dims=:, init=Int16(0)) === 2 +@test isequal(count(identity, [true false; false true], dims=2, init=UInt(0)), reshape(UInt[1, 1], 2, 1)) ## cumsum, cummin, cummax diff --git a/test/reducedim.jl b/test/reducedim.jl index 6a6f20214058c..1664b2708d7e3 100644 --- a/test/reducedim.jl +++ b/test/reducedim.jl @@ -88,12 +88,12 @@ safe_minabs(A::Array{T}, region) where {T} = safe_mapslices(minimum, abs.(A), re @test @inferred(count(!, Breduc, dims=region)) ≈ safe_count(.!Breduc, region) @test isequal( - @inferred(count(Breduc, dims=region, init=0x02)), - safe_count(Breduc, region) .% UInt8 .+ 0x02, + @inferred(Array{UInt8,ndims(Breduc)}, count(Breduc, dims=region, init=0x00)), + safe_count(Breduc, region), ) @test isequal( - @inferred(count(!, Breduc, dims=region, init=Int16(0))), - safe_count(.!Breduc, region) .% Int16, + @inferred(Array{Int16,ndims(Breduc)}, count(!, Breduc, dims=region, init=Int16(0))), + safe_count(.!Breduc, region), ) end @@ -693,7 +693,7 @@ end @test_throws TypeError count!([1], [1]) end -@test @inferred(count(false:true, dims=:, init=0x0004)) === 0x0005 +@test @inferred(UInt16, count(false:true, dims=:, init=0x0000)) === 1 @test @inferred(count(isodd, reshape(1:9, 3, 3), dims=:, init=Int128(0))) === Int128(5) @testset "reduced_index for BigInt (issue #39995)" begin