niku
As you know, Erlang and Elixir have a good specifications/functions for binary. However, I haven’t found it for bitstring. Here is some examples I ran into. I’m happy to hear your thoughts and solutions. Please let me know ![]()
Making a value
Sometimes you desire making a value as you read such as “00010010_10101011”.
It’s easy for binary with using integer literal starting 0b and :binary.encode_unsigned/1.
iex(1)> a = 0b00010010_10101011
4779
iex(2)> b = :binary.encode_unsigned(a)
<<18, 171>>
iex(3)> bit_size(b)
16
iex(4)> i b
Term
<<18, 171>>
Data type
BitString
Byte size
2
Description
This is a binary: a collection of bytes. It's printed with the `<<>>`
syntax (as opposed to double quotes) because it is not a UTF-8 encoded
binary (the first invalid byte being `<<171>>`)
Reference modules
:binary
Implemented protocols
Collectable, IEx.Info, Inspect, List.Chars, String.Chars
However, :binary.encode_unsigned/1 always makes a binary, I haven’t found the best practice for making a bitstring. Here is some techniques I use currently:
iex(1)> <<0::1, 1::1, 0::1, 1::1, 1::1>>
<<11::size(5)>>
iex(2)> # It's a little bit verbose but It works well
nil
iex(3)> <<0b01011::5>>
<<11::size(5)>
iex(4)> # It's simple but requires size explicitly
nil
and also using sigil which I have implemented.
iex(7)> import BitsSigils
BitsSigils
iex(8)> ~b(01011)
<<11::size(5)>>
iex(9)> # I like this, but needs to implement some codes
nil
Concatinating
For binary, We use <>/2 to concatinate.
iex(1)> a = "abc"
"abc"
iex(2)> b = "123"
"123"
iex(3)> a <> b
"abc123"
For bitstring, I can’t use both <>/2 and just <<>>/2.
iex(1)> a = <<1::1>>
<<1::size(1)>>
iex(2)> b = <<0::1>>
<<0::size(1)>>
iex(3)> a <> b
** (ArgumentError) argument error
(stdlib) eval_bits.erl:101: :eval_bits.eval_exp_field1/6
(stdlib) eval_bits.erl:92: :eval_bits.eval_field/3
(stdlib) eval_bits.erl:68: :eval_bits.expr_grp/4
(stdlib) erl_eval.erl:484: :erl_eval.expr/5
(iex) lib/iex/evaluator.ex:257: IEx.Evaluator.handle_eval/5
(iex) lib/iex/evaluator.ex:237: IEx.Evaluator.do_eval/3
iex(3)> <<a, b>>
** (ArgumentError) argument error
(stdlib) eval_bits.erl:101: :eval_bits.eval_exp_field1/6
(stdlib) eval_bits.erl:92: :eval_bits.eval_field/3
(stdlib) eval_bits.erl:68: :eval_bits.expr_grp/4
(stdlib) erl_eval.erl:484: :erl_eval.expr/5
(iex) lib/iex/evaluator.ex:257: IEx.Evaluator.handle_eval/5
(iex) lib/iex/evaluator.ex:237: IEx.Evaluator.do_eval/
So, I use <<>>/2 with segment types( ::bitstring).
iex(3)> <<a::bitstring, b::bitstring>>
<<2::size(2)>>
Converting into integer
For binary, we have nice functions thanks for :binary module. Unfortunary, It doesn’t work for bitstring.
iex(1)> :binary.decode_unsigned(<<1, 255>>)
511
iex(2)> :binary.decode_unsigned(<<1::1, 255>>)
** (ArgumentError) argument error
(stdlib) :binary.decode_unsigned(<<255, 1::size(1)>>)
I use pattern matching converting bitstring to integer. Please note you can only use integer or variable for size of bitstring in <<>>/2 .
iex(1)> a = <<1::1, 255>>
<<255, 1::size(1)>>
iex(2)> <<x::integer-size(bit_size(a))>> = a
** (CompileError) iex:2: size in bitstring expects an integer or a variable as argument, got: :erlang.bit_size(a)
(elixir) src/elixir_bitstring.erl:197: :elixir_bitstring.expand_each_spec/5
(elixir) src/elixir_bitstring.erl:168: :elixir_bitstring.expand_specs/6
(elixir) src/elixir_bitstring.erl:41: :elixir_bitstring.expand/8
(elixir) src/elixir_bitstring.erl:10: :elixir_bitstring.expand/4
iex(2)> b = bit_size(a)
9
iex(3)> <<x::integer-size(b)>> = a
<<255, 1::size(1)>>
iex(4)> x
511
Trending in Questions
Other Trending Topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #blog-post
- #elixir-ls
- #ai
- #elixirconf-us
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #hex
- #security
- #metaprogramming










Showing Posts 1 to 2- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
dimitarvp
Based on a quick search in hex.pm I found these might be of help for you:
Didn’t notice any of them offering a merge of two bitstrings but maybe it can be made to work with their functions.
jmitchell
Nice overview of different challenges and approaches. Recently I’ve been asking some of these questions too.
Is the bitstring you expect the same as the
:binary.encode_unsigned/1result, except with the leading0bits removed? If so, when you’d prefer to start from an integer rather than explicit bits using your niftyBitSigilsmodule, this may help:Usage:
This is the approach I’ve landed on too. You may appreciate this
flatten_bitstrings/1function. It’s similar toIO.iodata_to_binary/1, except it works on bitstrings as well as binaries.Usage:
Assuming you still only care about unsigned integers, I’d do the inverse of what I suggested for converting from bitstrings to integers. That is, pad the front of the bitstring with zeros until it is a binary, and then use
:binary.decode_unsigned/1.Usage:
Hope that helps