# I have: Vector{UInt8}. I need: BitVector

**URL:** https://discourse.julialang.org/t/i-have-vector-uint8-i-need-bitvector/2286
**Category:** General Usage
**Created:** [February 24, 2017, 8:20pm UTC](https://discourse.julialang.org/t/i-have-vector-uint8-i-need-bitvector/2286 "2017-02-24T20:20:43Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![anon94023334](https://avatars.discourse-cdn.com/v4/letter/a/e274bd/32.png) [@anon94023334](https://discourse.julialang.org/u/anon94023334)
#### Post date: [February 24, 2017, 8:20pm UTC](https://discourse.julialang.org/t/i-have-vector-uint8-i-need-bitvector/2286/1 "2017-02-24T20:20:43Z")

</div>

I have

```julia
julia> z
3-element Array{UInt8,1}:
 0x66
 0x6f
 0x6f

```

What I’d like is the (24-element) BitVector representation of this sequence. However, my attempt to use `reinterpret` yielded a very confusing error:

```julia
julia> reinterpret(BitArray{1}, z)
ERROR: ArgumentError: cannot reinterpret Array{UInt8} to ::Type{Array{BitArray{1}}}, type BitArray{1} is not a bitstype
 in reinterpret(::Type{BitArray{1}}, ::Array{UInt8,1}, ::Tuple{Int64}) at ./array.jl:87
 in reinterpret(::Type{BitArray{1}}, ::Array{UInt8,1}) at ./array.jl:75

```

Is there an efficient way to get a BitVector from `z`?

(Edited to add: discount any endianness issues for the moment; I can probably work around those.)

---

<div class="post-metadata">

### Author: ![m-j-w](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/m-j-w/32/4541_2.png) [@m-j-w](https://discourse.julialang.org/u/m-j-w)
#### Post date: [February 24, 2017, 9:02pm UTC](https://discourse.julialang.org/t/i-have-vector-uint8-i-need-bitvector/2286/2 "2017-02-24T21:02:59Z")

</div>

As mentioned on gitter, here’s an iterative approach:

```julia
zs = [0x1, 0x2, 0x3]
b = BitVector()
for z in zs
    append!(b, [z & (0x1<<n) != 0 for n in 0:7])
end

```

Possibly you may figure something out with creating a bitvector of the target size with `BitVector(24)` for 24 bits, then assign 8 values via `b[1:8] = ...; b[9:16] = ...` etc.  
But I didn’t find a fast and easy way to make a bitvector from each bit of an `UInt8` in one shot.

**Edit**  
Actually, the combination of the above also appears to work with broadcasting:

```julia
z = 0x12
b[1:8] .= [z & (0x1<<n) != 0 for n in 0:7]

```

Looks a bit fancier.

---

<div class="post-metadata">

### Author: ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)
#### Post date: [February 24, 2017, 9:12pm UTC](https://discourse.julialang.org/t/i-have-vector-uint8-i-need-bitvector/2286/3 "2017-02-24T21:12:33Z")

</div>

`reinterpret` takes the element type as the first value but there is no element type `Bit`.

---

<div class="post-metadata">

### Author: ![greg\_plowman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/greg_plowman/32/8100_2.png) [@greg\_plowman](https://discourse.julialang.org/u/greg_plowman)
#### Post date: [February 25, 2017, 3:38am UTC](https://discourse.julialang.org/t/i-have-vector-uint8-i-need-bitvector/2286/4 "2017-02-25T03:38:55Z")

</div>

BitArray is a composite type, not a bitstype so reinterpret won’t work directly.

```julia
  type BitArray{N} <: DenseArray{Bool,N}

  Fields:

  chunks :: Array{UInt64,1}
  len :: Int64
  dims :: Tuple{Vararg{Int64,N}}

```

You could do something like the following (but it does seem a bit hacky, so not really sure if recommended)

```julia
a = UInt8[0x66, 0x6f, 0x6f]
b = append!(copy(a), fill(UInt8(0), 5)) # pad to UInt64 size
c = reinterpret(UInt64, b)
B = BitVector(24)
B.chunks = c

```

---

<div class="post-metadata">

### Author: ![ScottPJones](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/scottpjones/32/146_2.png) [@ScottPJones](https://discourse.julialang.org/u/ScottPJones)
#### Post date: [February 25, 2017, 4:26am UTC](https://discourse.julialang.org/t/i-have-vector-uint8-i-need-bitvector/2286/5 "2017-02-25T04:26:16Z")

</div>

```julia
function make_bitvector(v::Vector{UInt8})
    siz = sizeof(v)
    bv = falses(siz<<3)
    unsafe_copy!(reinterpret(Ptr{UInt8}, pointer(bv.chunks)), pointer(v), siz)
    bv
end

function make_bitvector(v::Vector{UInt8}, dim::Integer)
    siz = sizeof(v)
    (((dim + 63) >>> 6) << 3) < siz && error("$dim too small for size $siz vector")
    bv = falses(dim)
    unsafe_copy!(reinterpret(Ptr{UInt8}, pointer(bv.chunks)), pointer(v), siz)
    bv
end

```

These functions should do the job. The second form allows you to set the number of bits in the resulting BitVector, instead of just having it be the size of the input vector of bytes \* 8 (it may need a bit more work to mask off bits \> number of bits set, but it’s a start.  
These should be faster than the other approaches discussed here.

---

<div class="post-metadata">

### Author: ![Mikhail\_Kagalenko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mikhail_kagalenko/32/13257_2.png) [@Mikhail\_Kagalenko](https://discourse.julialang.org/u/Mikhail_Kagalenko)
#### Post date: [May 18, 2022, 9:17am UTC](https://discourse.julialang.org/t/i-have-vector-uint8-i-need-bitvector/2286/6 "2022-05-18T09:17:21Z")

</div>

> [@ScottPJones](#):
>
> it may need a bit more work to mask off bits \> number of bits set

Why? The resulting BitVector won’t return elements with index greater than `dim`, will it?

---

<div class="post-metadata">

### Author: ![ScottPJones](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/scottpjones/32/146_2.png) [@ScottPJones](https://discourse.julialang.org/u/ScottPJones)
#### Post date: [May 25, 2022, 4:59am UTC](https://discourse.julialang.org/t/i-have-vector-uint8-i-need-bitvector/2286/7 "2022-05-25T04:59:28Z")

</div>

I wasn’t sure if some of the BitVector operations might have assumptions such as the chunks only contain 1 bits for valid bits (this makes doing things like counting the 1 bits slightly easier)
