# Parse an array of bits (\`BitArray\`) to an integer

**URL:** <https://discourse.julialang.org/t/parse-an-array-of-bits-bitarray-to-an-integer/42361>\
**Category:** New to Julia\
**Tags:** question\
**Created:** [July 1, 2020, 11:41am UTC](https://discourse.julialang.org/t/parse-an-array-of-bits-bitarray-to-an-integer/42361 "2020-07-01T11:41:45Z")\
**Posts on this page:** 8\
**Page:** 2

<div class="post-metadata">

**Author:** ![simeonschaub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simeonschaub/32/216566_2.png) [@simeonschaub](https://discourse.julialang.org/u/simeonschaub)\
**Post date:** [July 1, 2020, 2:38pm UTC](https://discourse.julialang.org/t/parse-an-array-of-bits-bitarray-to-an-integer/42361/21 "2020-07-01T14:38:16Z")

</div>

Something like this:

```julia
function bitarray_to_vector_of_bits(a)
    len = size(a, 1)
    return [SBitVector{len}(sum(i -> UInt(col[i]) << (i-1), 1:len)) for col in eachcol(a)]
end

```

---

<div class="post-metadata">

**Author:** ![roi.holtzman](https://avatars.discourse-cdn.com/v4/letter/r/f05b48/32.png) [@roi.holtzman](https://discourse.julialang.org/u/roi.holtzman)\
**Post date:** [July 1, 2020, 2:45pm UTC](https://discourse.julialang.org/t/parse-an-array-of-bits-bitarray-to-an-integer/42361/22 "2020-07-01T14:45:45Z")

</div>

I see. So do you know why do I get numbers that are different from a straight forward calculation?

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [July 1, 2020, 3:04pm UTC](https://discourse.julialang.org/t/parse-an-array-of-bits-bitarray-to-an-integer/42361/23 "2020-07-01T15:04:22Z")

</div>

The code is assuming that each column has 64 elements, and it’s reinterpreting to `Int64` which can take both negative and positive values.

If you want a different type of integer, use e.g. `UInt64`. Fixing the number of elements per column is harder.

---

<div class="post-metadata">

**Author:** ![Seif\_Shebl](https://avatars.discourse-cdn.com/v4/letter/s/eada6e/32.png) [@Seif\_Shebl](https://discourse.julialang.org/u/Seif_Shebl)\
**Post date:** [July 1, 2020, 10:18pm UTC](https://discourse.julialang.org/t/parse-an-array-of-bits-bitarray-to-an-integer/42361/24 "2020-07-01T22:18:54Z")

</div>

Here is a fast version with zero allocations. You can also control the output through the optional argument `s`. If the array has more than 63 elements, you can set `s = 0.0` or `s = big(0)` to avoid `Int` overflow.

```julia
function bitarr_to_int5(arr,s=0)
    v = 1
    for i in view(arr,length(arr):-1:1)
        s += v*i
        v <<= 1
    end 
    s
end

arr = BitArray(rand(0:1,50))
@btime bitarr_to_int($arr)
@btime bitarr_to_int2($arr)

  391.547 ns (2 allocations: 992 bytes)
  51.622 ns (0 allocations: 0 bytes)

```

---

<div class="post-metadata">

**Author:** ![cshen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cshen/32/217287_2.png) [@cshen](https://discourse.julialang.org/u/cshen)\
**Post date:** [October 18, 2020, 11:12am UTC](https://discourse.julialang.org/t/parse-an-array-of-bits-bitarray-to-an-integer/42361/25 "2020-10-18T11:12:00Z")

</div>

Sorry for the necrobump, but i might have found another version that is a little bit faster that the accepted solution and thought of leaving this here for future lurkers 😃 (maybe this is due to some change in julia itself, not sure)

```julia
function bitarr_to_int(arr, val = 0)
    v = 2^(length(arr)-1)
    for i in eachindex(arr)
        val += v*arr[i]
        v >>= 1
    end
    return val
end

function bitarr_to_int2(arr, val = 0)
    v = 1
    for i in view(arr, length(arr):-1:1)
        val += v*i
        v <<= 1
    end
    return val
end

b = BitArray(rand(0:1, 50))
@btime bitarr_to_int($b)
@btime bitarr_to_int2($b)

  69.902 ns (0 allocations: 0 bytes)
  91.101 ns (0 allocations: 0 bytes)

```

---

<div class="post-metadata">

**Author:** ![HyperSphereStudio](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hyperspherestudio/32/32322_2.png) [@HyperSphereStudio](https://discourse.julialang.org/u/HyperSphereStudio)\
**Post date:** [July 25, 2022, 11:48pm UTC](https://discourse.julialang.org/t/parse-an-array-of-bits-bitarray-to-an-integer/42361/26 "2022-07-25T23:48:52Z")

</div>

I actually just faced this problem in one of my libraries of converting between Integers & BitArrays as fast as possible. Unfortunately I do this conversion a lot so its definitely a hotspot! Here is my solution, though it seems to be slower then the accepted solution for small values (num\_bits \<= 64) when converting to/from BigInts. I built this to specifically handle very very large numbers of bits. Let me know if you see any improvements I could do to it!

Note: I do not think this will work on a 32 bit processor because BitArray has a UInt64 limb type rather then UInt.

```julia
const FastIntConversionType = Union{Base.BitSignedSmall, Base.BitUnsignedSmall, UInt64, Int64}

Base.convert(::Type{BitArray}, i::T) where T <: FastIntConversionType = convert(BitArray, reinterpret(UInt, Int(i)))

function Base.convert(::Type{BitArray}, i::UInt)
    bits = BitArray(undef, sizeof(UInt))
    bits.chunks[1] = reinterpret(UInt, i)
    return bits
end

function Base.convert(::Type{BitArray}, i::BigInt)
    GC.@preserve i begin
        bits = BitArray(undef, i.alloc * sizeof(UInt64))
        unsafe_copyto!(pointer(bits.chunks), i.d, length(bits.chunks))
        return bits
    end
end

function Base.convert(::Type{BigInt}, v::BitArray) 
    GC.@preserve v begin
        num = BigInt(; nbits = Int(8 * ceil(length(v) / 8)))
        limbs = num.alloc
        ptr = Base.GMP.MPZ.limbs_write!(num, limbs)
        unsafe_copyto!(ptr, pointer(v.chunks), length(v.chunks))
        Base.GMP.MPZ.limbs_finish!(num, -limbs)
        return num
    end
end

Base.convert(::Type{Integer}, i::BitArray) = length(i) > 8 * sizeof(Int) ? convert(BigInt, i) : convert(Int, i) 
Base.convert(::Type{T}, i::BitArray) where T <: FastIntConversionType = reinterpret(T, i.chunks[1])

```

---

<div class="post-metadata">

**Author:** ![Tobe\_Freeman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tobe_freeman/32/26435_2.png) [@Tobe\_Freeman](https://discourse.julialang.org/u/Tobe_Freeman)\
**Post date:** [November 22, 2022, 5:56pm UTC](https://discourse.julialang.org/t/parse-an-array-of-bits-bitarray-to-an-integer/42361/27 "2022-11-22T17:56:12Z")

</div>

arr = BitArray([1,0,1,0])  
What happened to Int64.(arr)?

---

<div class="post-metadata">

**Author:** ![ellocco](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ellocco/32/31331_2.png) [@ellocco](https://discourse.julialang.org/u/ellocco)\
**Post date:** [May 11, 2023, 11:52am UTC](https://discourse.julialang.org/t/parse-an-array-of-bits-bitarray-to-an-integer/42361/28 "2023-05-11T11:52:44Z")

</div>

Another option is:

```julia
bool2int(_boolarr) = evalpoly(2, reverse(_boolarr))

```

[see: vector-bool-to-int](https://discourse.julialang.org/t/vector-bool-to-int/89560/12)

[Previous page](https://discourse.julialang.org/t/parse-an-array-of-bits-bitarray-to-an-integer/42361.md?page=1)
