# Binary to integer (no parsing)

Hi,

Is there a function that would convert `<<1>>` to `1`, `<<1, 0>>` to `256`. I do not mean parsing the binary as a string representation of the integer.

I want to know how bing a 20 bytes integer can be.

``````b = 1..20 |> Enum.map(fn _ -> 255 end) |> :erlang.list_to_binary
<<255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255>>
``````

Thank you.

1 Like

If youâ€™re just doing one number, you can use pattern matching likr this:

``````<<number::16>> = <<1, 0>>
``````

And that will give you 256. This strategy will work for a 20 byte integer (obviously not with 16). Though if youâ€™re using it as a literal I recommend `number=0xFFFFFFFF....FFFFF`

1 Like
``````iex(2)> <<int::integer-size(2)-unit(8)>> = <<255, 255>>
<<255, 255>>
iex(3)> int
65535
``````
3 Likes

Not builtin, you have to implement that on your own. Though thats not an easy task, as there are meany questions you didnâ€™t even ask, like endianess or signedness.

20 bytes are 160 bits. Setting them all to `1` is 2^160 - 1 in unsigned interpretation.

Actually I wanted to know the number of possible values, sorry for the XY question. But I am still interested in writing such function.

Say unsigned big endian. I came up with that. It seems to work, but I find it unsatisfying:

``````
expected = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
^expected = 1_461_501_637_330_902_918_203_684_832_716_283_019_655_932_542_975

defmodule T do
def to_int(bin, endianness \\ :big) do
list =
bin
|> :erlang.binary_to_list()

case endianness do
:big -> :lists.reverse(list)
:little -> list
end
|> Enum.with_index()
|> Enum.reduce(0, fn {byte, i}, acc ->
acc + byte * round(:math.pow(256, i))
end)
end
end

256 = T.to_int(<<1, 0>>)

^expected =
T.to_int(
<<255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255>>
)

System.halt()
``````

(edit: I guess with signed ints we could abuse the binary_to_term function by adding <<131,98>> in front and making sure the binary length is a multiple of 4 bytes â€¦)

There are 2^n possible values in n bits.

3 Likes
``````fn bin ->
size = :erlang.size(bin) * 8
<<n::size(size)>> = bin
n
end
``````

If you want to play with endianness and what not there are binary pattern matching options you can shove into that match.

Try :binary.decode_unsigned/1,2, it does exactly what your code doesâ€¦

8 Likes

that function is kind of overcomplicated, consider (untested):

``````def to_int (<<>>, acc \\ 0), do: acc
def to_int (<<byte, rest::binary>>, acc \\ 0), do: to_int(rest, acc * 256 + byte)
``````

little-endian left as an exerciseâ€¦

Thank you all