# Converting BitVector arbitrary length components into UInt64, Float64, etc

**URL:** <https://discourse.julialang.org/t/converting-bitvector-arbitrary-length-components-into-uint64-float64-etc/63829>\
**Category:** New to Julia\
**Created:** [June 30, 2021, 12:58pm UTC](https://discourse.julialang.org/t/converting-bitvector-arbitrary-length-components-into-uint64-float64-etc/63829 "2021-06-30T12:58:54Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![costrouc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/costrouc/32/6506_2.png) [@costrouc](https://discourse.julialang.org/u/costrouc)\
**Post date:** [June 30, 2021, 12:58pm UTC](https://discourse.julialang.org/t/converting-bitvector-arbitrary-length-components-into-uint64-float64-etc/63829/1 "2021-06-30T12:58:54Z")

</div>

Hey all! New to Julia and was looking apply a use case I have to better understand the language. I have binary packet data similar to a network packet ethernet/ip/tcp where I need to be able to convert packets and their respective layers. The complication of this problem is I need to be able to account for endian-ness as well as I’ll want to convert a 3 bit unisigned int into preferably an UInt64. I’m interested in julia on how I could use macros to generate the struct as well as the logic to parse. e.g.

```julia
@parse (:EthernetFrame, :bigedian, [
     Field(:destination, UInt16, offset=0, length=48),
     Field(:ethtype, UInt8, offset=96, length=16),
     ...
])

```

Notice how some bits are not used. Ideally this would generate

```julia
struct EthernetFrame
    destination::UInt16
    ethtype::UInt8
end

# function to parse bitvector to create struct from description.
EthernetPacket(data::BitVector) = ... 

```

Any ideas on how to convert say a BitVector of length 3 bits to a UInt64, Float64, etc.?

Would this require masking and is there a performant way in Julia?

---

<div class="post-metadata">

**Author:** ![cdawg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cdawg/32/9811_2.png) [@cdawg](https://discourse.julialang.org/u/cdawg)\
**Post date:** [June 30, 2021, 1:38pm UTC](https://discourse.julialang.org/t/converting-bitvector-arbitrary-length-components-into-uint64-float64-etc/63829/2 "2021-06-30T13:38:34Z")

</div>

Recently used simple for loop to write the bits, setting thing with inplace-bitwiseor-updates `|=` and bitshifts (\<\< , \>\>\>). Something like

```julia
function packbits(::Type{T<:Int}, stream) where T
dest = zero(T)
for (b, bool) in enumerate(stream)
if bool
    dest |= one(T) << (b - 1)
end
end
return dest
end

```

“T” is your Int type. endian information could also be passed as type parameters in a similar way so the branch is compiled away. Could probably yet faster if you are more careful about your iteration.

I think the type system has enough power without macros to cover all your bases in a performant way but I am not a macro-user by the rule. Tricky to cover signed and unsigned stuff at the same time. Looks like a weekend CompSci homework problem 😛
