UInt8 access Bits?

Hi, guys,
is there a way to query or flip specific bits?

julia> binary = 0b111
0x07

julia> bitstring(binary)
"00000111"

julia> typeof(binary)
UInt8

In this case the following results would be expected:

binary[1] == binary[2] == binary[3] == 1

and for all all N greater than 3 (within half the limits)

binary[4] == ... == binary[N] == 0

how could I perform such a thing? how could I possibly perform this performant?

thanks.

a=digits(binary, base=2, pad=8)

stolen from here:

4 Likes

I know that in theory I could just look at the bit shifts, but that sounds unnecessarily complicated. Is there no way to access the memory directly at a location?

here the number is probably converted to an array every time, right? is there maybe a more performant version?

i have to do many lookups for many different numbers and converting the number each time is not performant

You’ll be much better off just using shift and bitwise operation.

binary & (UInt8(1) << 2) (access bit) or binary | (UInt8(1) << 2) (set bit) or binary & ~(UInt8(1) << 2) (unset bit)

7 Likes

So exactly what i wanted to do would be a way to count the number of True bits in a number. would you always shift to the right and check at the first position if the number % 2 == 0 is ergo if or if not the 1 bit is set is a good choice? or how would you do something like that to perform better?

for the example above

julia> bitstring(binary)
"00000111"

i would like to get 3 because there 3 bits set as true

julia> bitstring(binary2)
"00100000000000000000000100111"

would be 5

I’m not sure if that’s just an example — but if that’s exactly what you want there’s a function for it: count_ones.

4 Likes

Whether it’s just an example or exactly what you want to do, using the bit operations as I showed is exactly how you’d implement it. On top of that, there are tricks/estabilished patterns for almost all of the common operations that you might want and compilers can also do pattern matching for to for further optimizaion.

1 Like

And somehow I missed that part initially.

  1. Bit shift is not complicated, in fact it’s much simpler than accessing memory.
  2. There’s no memory to access here, different bits do not have different memory location.

Now if you are talking about syntax only and if you just want to have a shorter syntax to write, and what you mean by accessing memory is the [] syntax then sure, you can implement it yourself. And I won’t even bother implementing the [] syntax but just a function like setbit, testbit would work, very similar to what I did here. In any case, bit shifting is what you must do (even for the digits version, you just do much more useless stuff at the same time) but you can hide that behind whatever syntax you like…

2 Likes

You can use the lightweight Bits package:

julia> using Bits

julia> binary = bits(0b111)
<00000111>

julia> binary[1] == binary[2] == binary[3] == 1
true

julia> binary[4]
false

julia> collect(binary)
8-element Vector{Bool}:
 1
 1
 1
 0
 0
 0
 0
 0
3 Likes