Search code examples
binaryjuliabitmask

Finding the location of ones in a bit mask - Julia


I have a series of values that are each being stored as UInt16. Each of these numbers represents a bitmask - these numbers are commands that have been sent to a microprocessor telling it which pins to set high or low. I would like to parse this arrow of commands to find out which pins were being set high each time in such a way that is easier to analyse later.

Consider the example value 0x3c00, which in decimal is 15360 and in binary is 0011110000000000. Currently I have the following function

function read_message(hex_rep)
    return findall.(x -> x .== '1',bitstring(hex_rep))
end

Which gets called on every element of the array of UInt16. Is there a better/more efficient way of doing this?


Solution

  • The best approach probably depends on how you want to handle vectors of hex-values. But here's an approach for processing a single hex which is much faster than the one in the OP:

     function readmsg(x::UInt16)
        N = count_ones(x)
        inds = Vector{Int}(undef, N)
        if N == 0
            return inds
        end
        k = trailing_zeros(x)
        x >>= k + 1
        i = N - 1
        inds[N] = n = 16 - k
        while i >= 1
            (x, r) = divrem(x, 0x2)
            n -= 1
            if r == 1
                inds[i] = n
                i -= 1
            end
        end
        return inds
    end