我有一系列值,每个值都存储为UInt16
。这些数字中的每一个都代表一个位掩码——这些数字是被发送到微处理器的命令,告诉它哪个引脚设置为高或低。我想解析这个命令箭头,以找出每次设置高的引脚,以便以后更容易分析。
考虑示例值0x3c00
,其十进制为15360
,二进制为0011110000000000
。目前我有以下函数
function read_message(hex_rep)
return findall.(x -> x .== '1',bitstring(hex_rep))
end
在UInt16
数组的每个元素上调用。有没有更好/更有效的方法来做这件事?
最好的方法可能取决于您想如何处理十六进制值的向量。但是这里有一种处理单个十六进制的方法,它比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
我可以建议将向量填充到Vector{UInt64}
中,并使用它来手动构建BitVector
。以下内容应该可以正常工作(即使对于UInt16
以外的输入元素类型),但是我没有考虑到您可能想要尊重的特定端序:
julia> function read_messages(msgs)
bytes = reinterpret(UInt8, msgs)
N = length(bytes)
nchunks, remaining = divrem(N, sizeof(UInt64))
padded_bytes = zeros(UInt8, sizeof(UInt64) * cld(N, sizeof(UInt64)))
copyto!(padded_bytes, bytes)
b = BitVector(undef, N * 8)
b.chunks = reinterpret(UInt64, padded_bytes)
return b
end
read_messages (generic function with 1 method)
julia> msgs
2-element Vector{UInt16}:
0x3c00
0x8000
julia> read_messages(msgs)
32-element BitVector:
0
0
0
0
0
0
0
0
0
⋮
0
0
0
0
0
0
0
1
julia> read_messages(msgs) |> findall
5-element Vector{Int64}:
11
12
13
14
32
julia> bitstring.(msgs)
2-element Vector{String}:
"0011110000000000"
"1000000000000000"
(摆脱undef
位向量的不必要分配需要一些黑魔法,我相信。)