diff --git a/base/bitarray.jl b/base/bitarray.jl index 6ef76b3289f57..2a94fb68216d2 100644 --- a/base/bitarray.jl +++ b/base/bitarray.jl @@ -1446,7 +1446,16 @@ end # returns the index of the next non-zero element, or 0 if all zeros function findnext(B::BitArray, start::Integer) Bc = B.chunks - for i = div(start-1,64)+1:length(Bc) + + chunk_start = @_div64(start-1)+1 + within_chunk_start = @_mod64(start-1) + mask = _msk64 << within_chunk_start + + if Bc[chunk_start] & mask != 0 + return (chunk_start-1) << 6 + trailing_zeros(Bc[chunk_start] & mask) + 1 + end + + for i = chunk_start+1:length(Bc) if Bc[i] != 0 return (i-1) << 6 + trailing_zeros(Bc[i]) + 1 end @@ -1462,7 +1471,16 @@ function findnextnot(B::BitArray, start::Integer) if l == 0 return 0 end - for i = div(start-1,64)+1:l-1 + + chunk_start = @_div64(start-1)+1 + within_chunk_start = @_mod64(start-1) + mask = ~(_msk64 << within_chunk_start) + + if Bc[chunk_start] | mask != _msk64 + return (chunk_start-1) << 6 + trailing_ones(Bc[chunk_start] | mask) + 1 + end + + for i = chunk_start+1:l-1 if Bc[i] != _msk64 return (i-1) << 6 + trailing_ones(Bc[i]) + 1 end diff --git a/test/bitarray.jl b/test/bitarray.jl index f8c9e29af2e5e..9ac726b8d96e9 100644 --- a/test/bitarray.jl +++ b/test/bitarray.jl @@ -520,6 +520,20 @@ b1 = randbool(v1) @check_bit_operation find Vector{Int} (b1,) +b1 = trues(v1) +for i = 0:v1-1 + @test findfirst(b1 >> i) == i+1 + @test Base.findfirstnot(~(b1 >> i)) == i+1 +end + +for i = 3:v1-1 + for j = 2:i + submask = b1 << (v1-j+1) + @test findnext((b1 >> i) | submask,j) == i+1 + @test Base.findnextnot((~(b1 >> i)) $ submask,j) == i+1 + end +end + b1 = randbool(n1, n2) @check_bit_operation findn_nzs (Vector{Int}, Vector{Int}, BitArray) (b1,)