# BitIntegers: creation in loop; how to avoid allocations?

**URL:** <https://discourse.julialang.org/t/bitintegers-creation-in-loop-how-to-avoid-allocations/115935>\
**Category:** General Usage\
**Created:** [June 20, 2024, 3:42pm UTC](https://discourse.julialang.org/t/bitintegers-creation-in-loop-how-to-avoid-allocations/115935 "2024-06-20T15:42:21Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Leo\_I](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/leo_i/32/27262_2.png) [@Leo\_I](https://discourse.julialang.org/u/Leo_I)\
**Post date:** [June 20, 2024, 3:42pm UTC](https://discourse.julialang.org/t/bitintegers-creation-in-loop-how-to-avoid-allocations/115935/1 "2024-06-20T15:42:21Z")

</div>

I asked this question in a GitHub [issue](https://github.com/rfourquet/BitIntegers.jl/issues/45) but got no replies:

I’d like to create all BitIntegers of byte length up to 1024. I don’t want to write 128 lines of code for that, so I’m trying to use a loop. Running the following code gives an error:

```julia
for k=8:8:1024 k∈(8,16,32,64,128) && continue;  
    @eval BitIntegers.@define_integers $k Int$k UInt$k end

ERROR: syntax: invalid type signature around /home/user/.julia/packages/BitIntegers/VJRl1/src/BitIntegers.jl:62
Stacktrace:
 [1] top-level scope
   @ none:1
 [2] eval(m::Module, e::Any)
   @ Core ./boot.jl:370
 [3] top-level scope
   @ REPL[11]:2

```

Running the code below works but does not create my UInt’s in the global scope:

```julia
for k=8:8:1024 k∈(8,16,32,64,128) && continue; 
    eval("BitIntegers.@define_integers $k Int$k UInt$k;") end

julia> UInt24
ERROR: UndefVarError: `UInt24` not defined

```

Is there a workaround for doing this?

Also, an unrelated question: If I create `Matrix{Int128}` and do row and column operations on it (like Smith normal form), that will cause no additional allocations. However, on `Matrix{Int1024}` there are many additional allocations. Is there a way to avoid this? Are `BitInteger`s still converting internally to `BigInt`s? If so, then what is the purpose of `BitInteger`s, what advantage do they offer compared to just using `BigInt`s from the start?

Theoretically, would it be possible to refactor this package in a way that `BitInteger`s would behave more like `Int64` and `Int128` with regard to allocations? Or is the inherent nature of CPUs and RAMs such that this is impossible? (I noticed there are no integers of custom byte sizes in rust, go, …, so I was wondering…)

---

<div class="post-metadata">

**Author:** ![thofma](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/thofma/32/1691_2.png) [@thofma](https://discourse.julialang.org/u/thofma)\
**Post date:** [June 20, 2024, 4:09pm UTC](https://discourse.julialang.org/t/bitintegers-creation-in-loop-how-to-avoid-allocations/115935/2 "2024-06-20T16:09:13Z")

</div>

The following works for me:

```julia-repl
julia> for k=8:8:1024 k∈(8,16,32,64,128,512,1024) && continue;
           eval(Meta.parse("BitIntegers.@define_integers $k Int$k UInt$k;")); end

```

> Also, an unrelated question: If I create `Matrix{Int128}` and do row and column operations on it (like Smith normal form), that will cause no additional allocations. However, on `Matrix{Int1024}` there are many additional allocations. Is there a way to avoid this? Are `BitInteger` s still converting internally to `BigInt` s?

Are you doing divisions? Then see point 1) of the README [GitHub - rfourquet/BitIntegers.jl: Fixed-width integers similar to builtin ones](https://github.com/rfourquet/BitIntegers.jl).

> Or is the inherent nature of CPUs and RAMs such that this is impossible? (I noticed there are no integers of custom byte sizes in rust, go, …, so I was wondering…) (I noticed there are no integers of custom byte sizes in rust, go, …, so I was wondering…)

They don’t exist because there aren’t that many application. In my experience, either you want machine integers (aka `Int64`) for control flow and counting things, or you want to do some exact computations, in which case you want arbitrary large integers. An application that falls in the middle of these two is working efficiently modulo m (m an arbitrary integer). Then there exist special purpose libraries that implement fast operations modulo m by representing everything with a fixed number of bits.

---

<div class="post-metadata">

**Author:** ![Leo\_I](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/leo_i/32/27262_2.png) [@Leo\_I](https://discourse.julialang.org/u/Leo_I)\
**Post date:** [June 20, 2024, 4:31pm UTC](https://discourse.julialang.org/t/bitintegers-creation-in-loop-how-to-avoid-allocations/115935/3 "2024-06-20T16:31:37Z")

</div>

Thank you, it works for me too now. I just needed to add `256` to the tuple of ignored bitwidths.

Regarding allocations, so only `div` is causing allocations? Operations `+, *, mod, <<, >>` do not, even for 1024-width integers?

Yeah, `BitInteger`s can be also used to represent sets, as an alternative to `BitVector`s.

---

<div class="post-metadata">

**Author:** ![thofma](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/thofma/32/1691_2.png) [@thofma](https://discourse.julialang.org/u/thofma)\
**Post date:** [June 20, 2024, 5:15pm UTC](https://discourse.julialang.org/t/bitintegers-creation-in-loop-how-to-avoid-allocations/115935/4 "2024-06-20T17:15:56Z")

</div>

> [@Leo\_I](#):
>
> Regarding allocations, so only `div` is causing allocations? Operations `+, *, mod, <<, >>` do not, even for 1024-width integers?

I did a bit of benchmarking in the REPL and as far as I can tell, the answer is yes.

(@rfourquet: please correct me if I am wrong.)

---

<div class="post-metadata">

**Author:** ![matthias314](https://avatars.discourse-cdn.com/v4/letter/m/a88e4f/32.png) [@matthias314](https://discourse.julialang.org/u/matthias314)\
**Post date:** [June 20, 2024, 7:19pm UTC](https://discourse.julialang.org/t/bitintegers-creation-in-loop-how-to-avoid-allocations/115935/5 "2024-06-20T19:19:23Z")

</div>

> [@Leo\_I](#):
>
> `@eval BitIntegers.@define_integers $k Int$k UInt$k`

If you don’t want to use `Meta.parse`, you can say

```julia
@eval BitIntegers.@define_integers $k $(Symbol("Int", k)) $(Symbol("UInt", k))

```

---

<div class="post-metadata">

**Author:** ![sgaure](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sgaure/32/14779_2.png) [@sgaure](https://discourse.julialang.org/u/sgaure)\
**Post date:** [June 21, 2024, 9:15am UTC](https://discourse.julialang.org/t/bitintegers-creation-in-loop-how-to-avoid-allocations/115935/6 "2024-06-21T09:15:53Z")

</div>

> [@Leo\_I](#):
>
> Yeah, `BitInteger`s can be also used to represent sets, as an alternative to `BitVector`s.

If sets is your application, there is also the [GitHub - matthias314/SmallCollections.jl: A Julia package providing variable-length set and vector types that don't allocate](https://github.com/matthias314/SmallCollections.jl).

---

<div class="post-metadata">

**Author:** ![rfourquet](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rfourquet/32/3610_2.png) [@rfourquet](https://discourse.julialang.org/u/rfourquet)\
**Post date:** [March 18, 2025, 3:30pm UTC](https://discourse.julialang.org/t/bitintegers-creation-in-loop-how-to-avoid-allocations/115935/7 "2025-03-18T15:30:36Z")

</div>

A good news is that from julia v1.11 onwards, division is implemented by LLVM, so it doesn’t allocate anymore 🙂
