What is the difference between a Binary and a Bitstring in Erlang?

7.3k views Asked by At

In the Erlang shell, I can do the following:

A = 300.
    300
<<A:32>>.
    <<0, 0, 1, 44>>

But when I try the following:

B = term_to_binary({300}).
    <<131,104,1,98,0,0,1,44>>
<<B:32>>
    ** exception error: bad argument
<<B:64>>
    ** exception error: bad argument

In the first case, I'm taking an integer and using the bitstring syntax to put it into a 32-bit field. That works as expected. In the second case, I'm using the term_to_binary BIF to turn the tuple into a binary, from which I attempt to unpack certain bits using the bitstring syntax. Why does the first example work, but the second example fail? It seems like they're both doing very similar things.

2

There are 2 answers

1
Ben On BEST ANSWER

The difference between in a binary and a bitstring is that the length of a binary is evenly divisible by 8, i.e. it contains no 'partial' bytes; a bitstring has no such restriction.

This difference is not your problem here.

The problem you're facing is that your syntax is wrong. If you would like to extract the first 32 bits from the binary, you need to write a complete matching statement - something like this:

<<B1:32, _/binary>> = B.

Note that the /binary is important, as it will match the remnant of the binary regardless of its length. If omitted, the matched length defaults to 8 (i.e. one byte).

You can read more about binaries and working with them in the Erlang Reference Manual's section on bit syntax.

EDIT

To your comment, <<A:32>> isn't just for integers, it's for values. Per the link I gave, the bit syntax allows you to specify many aspects of binary matching, including data types of bound variables - while the default type is integer, you can also say float or binary (among others). The :32 part indicates that 32 bits are required for a match - that may or may not be meaningful depending on your data type, but that doesn't mean it's only valid for integers. You could, for example, say <<Bits:10/bitstring>> to describe a 10-bit bitstring. Hope that helps!

0
notriddle On

The <<A:32>> syntax constructs a binary. To deconstruct a binary, you need to use it as a pattern, instead of using it as an expression.

A = 300.
% Converts a number to a binary.
B = <<A:32>>.
% Converts a binary to a number.
<<A:32>> = B.