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
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 …)
I am gonna work in my free time on a fairly basic network protocol in Rust, Golang and Elixir, and I am starting with Elixir.
I need to be able to encode and decode unsigned 32-bit integers to/from byte buffers (big endian). While :binary.encode_unsigned(x, :big) works the protocol requires all 4 bytes be sent, and this function always finds the smallest possible representation: