I want to parse an array of bits to a decimal number.
I am using this function now but it does not work very fast
function bitarr_to_int(arr)
return sum(arr .* (2 .^ collect(length(arr)-1:-1:0)))
end
Is there a way to perform this conversion fast?
I tried to use parse but it only get strings, and I couldn’t convert the BitArray to a string properly.
Your original function uses BigInt? It seems to me that it just works over Ints. The bittest functions explicitly converts to BigInts. You were sure the original BitArray had not more than 63~64 elements?
If your array never contains more than 64 entries, you can just use arr.chunks[1]. I chose BigInt here, because your example overflows if there are more than 63 entries in arr.
I see. I know that my arrays are always < 60 entries, so I do not need the BigInt.
I want to run this conversion for 10^7 such arrays.
When I run both functions in a for loop, they give roughly the same result (your method is ~7 seconds, and my original function is ~11 seconds).
Is there a better way to run this for an entire 2d array (in the appropriate axis of course)?
arr.chunks[1] should basically be free. reverse might be expensive. The inplace reverse! might be a bit more efficient here, because it shouldn’t allocate. A better solution might be to restructure your code a bit, so you don’t need to reverse the array. It’s difficult to give concrete tips without knowing a bit more about your application. Are you currently using a 2d BitArray? If so, it might be a better solution to use a Vector{UInt} as your data structure and implement the bit-twiddling yourself.
Thanks for the answer.
I have a 2d array of bits. Each row is the bit array I am willing to convert to an int.
I guess I thought that even for 10^7 rows in such a 2d BitArray, the operation should be quite fast - my intuition was wrong.
It should be fast, if you can use .chunks and reinterpret, but you should be working along columns, not rows for good performance. Also, if each row/column has less than 60 elements, how do you wish to interpret the missing bits needed to make up a 64 bit integer?
julia> R = bitrand(64, 10^7); # working along the columns, not rows
julia> @btime reinterpret(Int64, ($R).chunks);
8.264 ns (1 allocation: 32 bytes) # fast enough?
With less than 64 elements you need to apply some bitmask or something.
I am actually working with columns (I wrote rows, because I thought it is more natural for understanding).
Each column has 20 rows - so it is a 20 bit number. I would like to read it as a 20 bit number - like padding all of first 44 bits with zeros.
I tried to run the reinterpret function you used. I do not understand the $ sign before the R. It does not run like this for me.
I ran reinterpret(Int64, (R).chunks) , but as a result I get also negative numbers, which should not be. So I do not really understand how this works.
Could you explain a bit more on how to use reinterpret here?
I am not sure I understand the context, but if possible, I would just consider building an UInt64 directly with | and 1 << index when processing the original data.
I think that you mean that you would not maintain the bit array, but just get the integer number?
I need the entire bit array, because I want to drop some of the bits by hand.
I did not follow on what you meant with | and 1<<index. Could you explain that? Maybe it could still help me somehow.
You can query bits in a similar way. This is basically what BitArray does under the hood, but in a much more organized way, allowing longer vectors etc, but if you need the basics it is really simple.