How to get the eight bit values of a variable with UInt8?

Now I’m reading a binary file. I have got a 8 bits namely “a”. According to the data description, each bit represents a different meaning, I want to read the value represented by 8 bit bits, how can I do it?

a = 0x0c # UInt8, little endian
a8 = ? # 
a7 = ?
a6 = ?
a5 = ?
a4 = ?
a3 = ?
a2 = ?
a1 = ?

The simplest is:

julia> a = 0x0c
julia> digits(a, base=2, pad=8)
8-element Vector{Int64}:
 0
 0
 1
 1
 0
 0
 0
 0
6 Likes

Thanks a lot. An elegant answer.

you can also do directly

bits(a::UInt8) = ntuple(i -> (a >> (i-1)) & one(a), 8)

which should be faster as it avoids allocation (3 times faster on my machine).

5 Likes

It generalizes well, also:

function bits(a::Integer)
   N = sizeof(a) * 8
   return ntuple(i -> (a >> (i-1)) & one(a), Val(N))
end

Example:

julia> @btime bits(x) setup=(x=rand(Int32))
  4.600 ns (0 allocations: 0 bytes)
(0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0)
4 Likes

There is also the Bits.jl package, which is a bit dusty, but has this bits function, which just (lazily) wraps an integer as an array of Bools:

julia> using Bits; bs = bits(0x0c)
<00001100>

julia> collect(bs)
8-element Vector{Bool}:
 0
 0
 1
 1
 0
 0
 0
 0

julia> bs[4]
true

julia> bs[1:4]
<1100>
2 Likes

Probably better to use Base.BitInteger there at the cost of excluding @rfourquet s BitIntegers.jl :wink: As written this will be not correct for heap allocated integers.

1 Like

:smiley: Good occasion to bump Feature request: add an AbstractBitSigned type · Issue #37752 · JuliaLang/julia · GitHub

You can usw bit-wise operations directly.

julia> a = 0x0c
0x0c

julia> bits = a .>> (0:7) .& 0x1
8-element Vector{UInt8}:
 0x00
 0x00
 0x01
 0x01
 0x00
 0x00
 0x00
 0x00

julia> f(a,s) = a >> s & 0x1
f (generic function with 1 method)

julia> f.(a, 0:7)
8-element Vector{UInt8}:
 0x00
 0x00
 0x01
 0x01
 0x00
 0x00
 0x00
 0x00
3 Likes

Using a comprehension:

a = 0x0c

[!iszero(a & <<(one(a), i)) for i in 0:7] 

# result:
8-element Vector{Bool}:
 0
 0
 1
 1
 0
 0
 0
 0
1 Like

My package Modulo2.jl has the function zz2vector:

julia> zz2vector(0x0c)
8-element ZZ2Vector:
 0
 0
 1
 1
 0
 0
 0
 0

It works with all bit sizes, including BitIntegers.jl.

If you’re OK with a string representation, there’s also bitstring:

julia> bitstring(0x0c)
"00001100"
2 Likes