At7heb
Extracting 15-bit integer values from binary with pattern matching
I have time deltas stored in a file in two formats:
0xxxxxxx
1yyyyyyyyyyyyyyy
In the first format, the time delta is the unsigned 7 bit field represented by xxxxxxx. In the second format, the time delta is the signed 15 bit field represented by yyyyyyyyyyyyyyy
pattern matching to extract the values works for the 7 bit unsigned case:
iex(12)> <<0::1, num::size(7)-unsigned-integer-little>> = <<2>>; num
2
But for the intuitive extension to the 15-bit signed case, it isn’t so obvious that it is working correctly:
iex(15)> <<1::1, num::size(15)-signed-integer-little>> = <<255,255>>; num
-1
That’s reasonable. However:
iex(14)> <<1::1, num::size(15)-signed-integer-little>> = <<254,255>>; num
-3
The value of the 15 bit signed field is -2, not -3.
I’ve been searching for the documentation fruitlessly, so a pointer to the place where I can read the fine documentation, or else just the answer, would be appreciated.
thanks…
Most Liked
At7heb
Thank you for the pointer to the erlang documentation. That looks like the syntax, with the : (erlang) vs. :: (elixir) difference.
Looking at that documentation inspired me to ask what elixir would construct, given the same layout as in the pattern, so I entered the following into iex. It seems that the affected bits are the least significant bits of the first byte and the most significant bits of the second byte.
Without a specification of how to place a 1 bit field and a 15-bit little endian field into two bytes, I can’t say I know how to write the elixir pattern,
I’m going to consider this as closed. (Not sure how to/if I can close a topic in this forum.) Thank you for your insights.
iex(57)> Enum.map(-16..16, &(<<0::1, &1::15-signed-little>> <> <<0>> <> <<&1::8>>))
[
<<120, 127, 0, 240>>,
<<120, 255, 0, 241>>,
<<121, 127, 0, 242>>,
<<121, 255, 0, 243>>,
<<122, 127, 0, 244>>,
<<122, 255, 0, 245>>,
<<123, 127, 0, 246>>,
<<123, 255, 0, 247>>,
<<124, 127, 0, 248>>,
<<124, 255, 0, 249>>,
<<125, 127, 0, 250>>,
<<125, 255, 0, 251>>,
<<126, 127, 0, 252>>,
<<126, 255, 0, 253>>,
<<127, 127, 0, 254>>,
<<127, 255, 0, 255>>,
<<0, 0, 0, 0>>,
<<0, 128, 0, 1>>,
<<1, 0, 0, 2>>,
<<1, 128, 0, 3>>,
<<2, 0, 0, 4>>,
<<2, 128, 0, 5>>,
<<3, 0, 0, 6>>,
<<3, 128, 0, 7>>,
<<4, 0, 0, 8>>,
<<4, 128, 0, 9>>,
<<5, 0, 0, 10>>,
<<5, 128, 0, 11>>,
<<6, 0, 0, 12>>,
<<6, 128, 0, 13>>,
<<7, 0, 0, 14>>,
<<7, 128, 0, 15>>,
<<8, 0, 0, 16>>
]







