# Implementing a wrapping addition for 32 bit integers

In most cases Elixir and Erlang intrinsically moving to BigInt is remarkably helpful and satisfying to work with, so I know this exercise is academic. Still if I wanted to work with integers as if they were restricted to signed 32-bit integers, how would I handle overflow/wrapping?
I’m thinking the easiest way is working with integers as binaries, something like:

``````x = Integer.pow(2, 32) - 1
<<x:32>> # returns <<255, 255, 255, 255>>
y = 1
<<y:32>> # returns <<0, 0, 0, 1>>
``````

If I try to do `<<(x + y)::32>>` I’ll get `<<0, 0, 0, 0>>`. What’s the best way to capture that overflow digit?

2 Likes

You want to capture overflow or to have wrapping addition? Because in wrapping addition `0xFFFF_FFFF + 1 == 0` not `1`.

2 Likes

Imprecise wording on my part, sorry. I meant how do I convert <<0,0,0,0>> (or whatever the wrapped result is) back to an integer.

``````x = Integer.pow(2, 32) - 1
<<x:32>> # returns <<255, 255, 255, 255>>
y = 1
<<y:32>> # returns <<0, 0, 0, 1>>
z = <<(x + y)::32>> # returns <<0, 0, 0, 0>>
``````

Is there a better way to get z into integer form without iterating over the binary as a list and reducing?

1 Like

If you want to treat bitstring as an unsigned-integer, and by default it will be an unsigned integer if we dont specify anything.

``````<<z::32>> = <<(x + y)::32>> # z = 0
<<z::32>> = <<(Integer.pow(2, 32)-1)::32>> # z = 4294967295
``````

But from your original description, it seems like you are interested in signed integer. For that it will be

``````<<z::signed-integer-size(32)>> = <<(x + y)::32>> # z = 0
<<z::signed-integer-size(32)>> = <<(Integer.pow(2, 32)-1)::32>> # z = -1
``````
2 Likes

`Bitwise.band/2`

maybe with `binary:decode_unsigned`

Earlier I was on mobile, now I can expand.

Addition of two N-bit integers can result with at most (N+1)-bit integer. So as we are adding 32-bit integers then we will end with at most 33-bit result. That will give us the knowledge to achieve what we want:

``````defmodule Carry do
@u32_max 2 ** 32 - 1

import Bitwise

r = a + b
{r &&& @u32_max, (r >>> 32) == 1}
end
end

a = 0xFFFF_FFFF
b = 1