Binaries

The binary type represents a sequence of bits.

A binary literal looks like << term,… >>.

The simplest term is just a number from 0 to 255. The numbers are stored as successive bytes in the binary.

 iex>​ b = << 1, 2, 3 >>
 <<1, 2, 3>>
 iex>​ byte_size b
 3
 iex>​ bit_size b
 24

You can specify modifiers to set any term’s size (in bits). This is useful when working with binary formats such as media files and network packets.

 iex>​ b = << 1::size(2), 1::size(3) >> ​# 01 001
 <<9::size(5)>> # = 9 (base 10)
 iex>​ byte_size b
 1
 iex>​ bit_size b
 5

You can store integers, floats, and other binaries in binaries.

 iex>​ int = << 1 >>
 <<1>>
 iex>​ float = << 2.5 :: float >>
 <<64, 4, 0, 0, 0, 0, 0, 0>>
 iex>​ mix = << int :: binary, float :: binary >>
 <<1, 64, 4, 0, 0, 0, 0, 0, 0>>

Let’s finish an initial look at binaries with an example of bit extraction. An IEEE 754 float has a sign bit, 11 bits of exponent, and 52 bits of mantissa. The exponent is biased by 1023, and the mantissa is a fraction with the top bit assumed to be 1. So we can extract the fields and then use :math.pow, which performs exponentiation, to reassemble the number:

 iex>​ << sign::size(1), exp::size(11), mantissa::size(52) >> = << 3.14159::float >>
 iex>​ (1 + mantissa / ​:math​.pow(2, 52)) * ​:math​.pow(2, exp-1023) * (1 - 2*sign)
 3.14159