Hacky way to get bit at index: Julia

This is quite hacky, but it definitely unblocked me while working on FIT.jl. In Garmin FIT files, each record has a byte header used to identify the message type. At position 6 in the byte header, we find the bit used to identify whether a message is a data message or a definition.

I know there are ways to isolate this bit using bitwise operators, but I settled on the below approach (knowing that this software at the moment is purely for myself).

parse(UInt8, bitstring(byte)[idx])

Why is this horribly inefficent?

Well, we are converting the byte into a string, indexing into the string grabbing a specific char, then converting back to our UInt8 type using `parse`. Wow, not great.

But it solves the problem!

Julia is an interactive language, you develop mainly within the REPL. So, having my single `bit_at` function be powered by this hacky method, I can easily swap out the impelementation later when needed.

One more cool feature, ranges.

In Julia, you can use a bit of syntactic sugar to define a range.

range = 1:1:8

This range means start at 1, end at 8, and have a step size of 1. So, I was able to extend this concept of ranges to implement the concept of little vs. big-endian in my bit-at code. Observe:

  function bit_vector(byte::UInt8; little_endian=false)::Vector{UInt8}
    range = if little_endian

    s = bitstring(byte)
    [parse(UInt8, s[b]) for b in range]

The vector of “bits” is generated using the list comprehension at the bottom of the function. `for b in range` is of special importance. I use `b` as the index of the bitstring `s`, and run that bit through my parse call described above. This gives me my desired effect of being a vector of “bits”, represented as `UInt8` bytes.

In action:

julia> bit_vector(0x40)
8-element Vector{UInt8}:


I run WindleWare! Feel free to reach out!

Subscribe for Exclusive Updates

* indicates required