how do you guys work with base2 binaries ...

803 views
Skip to first unread message

mraptor

unread,
Dec 4, 2013, 2:28:42 PM12/4/13
to elixir-l...@googlegroups.com
How do you assign, display, parse, slice ..purely binary (base2) values ..
The docs are a bit confusing on that... mostly oriented towards everything but 01-bins

binary is 8 bits, bitstring is 01-base2 ? or is it ? Is it bit-string OR bitstring OR binstring, which one is the base2 one ?
> "The type can be integer, float, bitstring/bits, binary/bytes, utf8, utf16 or utf32" , but this does not seem to work ..

iex(46)> <<00000011::bits>>
** (ArgumentError) argument error
iex(46)> <<00000011::bits>>

this :

iex(46)> <<00000011::8>>  
"\t"

is showing textual representation of the "?bitstring?"
Erlang declaration does not seem to work either :

iex(47)> 2#00000011    
2

I want to be able to assign arbitrarily long binary2, display it, splice/split it... and so on ?
So what I'm doing wrong...? Where my confusion comes from ?

thanks

José Valim

unread,
Dec 4, 2013, 4:31:10 PM12/4/13
to elixir-l...@googlegroups.com
binary is 8 bits, bitstring is 01-base2 ? or is it ? Is it bit-string OR bitstring OR binstring, which one is the base2 one ?
> "The type can be integer, float, bitstring/bits, binary/bytes, utf8, utf16 or utf32" , but this does not seem to work ..

bits are still integers so all you need is to represent the integer in base 2. You do that in Elixir as 0b00000011. If you want to do that dynamically, integer_to_binary/binary_to_integer are your friends.

Vincent Siliakus

unread,
Dec 4, 2013, 4:43:45 PM12/4/13
to elixir-l...@googlegroups.com
Out of curiosity, why do you want to do this?

Op woensdag 4 december 2013 20:28:42 UTC+1 schreef mraptor:

mraptor

unread,
Dec 4, 2013, 5:23:14 PM12/4/13
to elixir-l...@googlegroups.com
I'm doing some simple matrix operation in Perl PDL now.... but wasting 8 bits for a bit (PDL does not support bit-matricies/fields)..
And I wanted to experiment of doing something along the lines as learning exercise in Elixir. (not that it matters much, but this is something I'm currently fiddling with.. and may even give me some ideas if I decide to do it in C)

PS> In the low-side-spectrum I'm working with 20x3000 bit-fields, it can go to at least 100x50_000 ...   so the other thing I was wondering is so much data a good candidate if handled as immutable data..! Btw, I have no idea if Elixir provide some access to mutable data ?
PDL support threads, so it may be also good for speed comparison, If I can make it work...
Just looking for something to experiment with :)

Vincent Siliakus

unread,
Dec 5, 2013, 7:14:51 AM12/5/13
to elixir-l...@googlegroups.com
Interesting. You could use bitstrings for this, but matrix operations are absolutely not in my area of expertise, so I can't judge if it's actually a good fit.

The bitstring syntax can indeed be a bit confusing at first, but once you get the hang of it, it's actually pretty easy to use. If you want to create a 8bit bitstring out of single bits:

iex(1)> bits = <<0::size(1), 0::size(1), 0::size(1), 0::size(1), 0::size(1), 0::size(1), 1::size(1), 1::size(1)>>
<<3>>

If you want to unpack a 8bit bitstring into its individual bits, you could do it like this:

iex(2)> <<b8::size(1), b7::size(1), b6::size(1), b5::size(1), b4::size(1), b3::size(1), b2::size(1), b1::size(1)>> = bits
<<3>>

iex(3)> b1
1
iex(4)> b2
1
iex(5)> b3
0

etc.

You can use bitstring and list comprehensions to operate on single bits too.

Flip the bits:

iex(6)> flip_bit = fn 0 -> 1; 1 -> 0 end
#Function<6.80484245 in :erl_eval.expr/5>

iex(6)> bc <<b::size(1)>> inbits <<3>>, do: <<flip_bit.(b)::size(1)>>
<<252>>

unpack a 16bit bitstring to a list of bits:

iex(7)> lc <<b::size(1)>> inbits <<1023::size(16)>>, do: b                                                                        
[0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]

create an 8bit bitstring from a list of bits:

 iex(8)> bc b inlist [0,0,0,0,0,0,1,1], do: <<b::size(1)>>                                                                         
<<3>>

You can use ETS tables in Elixir when you need mutable data in RAM. It provides quite fast read and write operations. But as far as I know, the way ETS works doesn't allow you to update a bitstring, without reading the entire bitstring from the table, update it, and write it back to the table, so I doubt ETS tables will give you good performance for your use case.

Have fun experimenting :)




Op woensdag 4 december 2013 23:23:14 UTC+1 schreef mraptor:

mraptor

unread,
Dec 5, 2013, 10:11:35 AM12/5/13
to elixir-l...@googlegroups.com
Neat .. thank you :

> bc <<b::1>> inbits <<0b00001110::8>>, do: <<b>>
<<0, 0, 0, 0, 1, 1, 1, 0>>

still confusing though :))

Vincent Siliakus

unread,
Dec 5, 2013, 11:16:42 AM12/5/13
to elixir-l...@googlegroups.com
Op donderdag 5 december 2013 16:11:35 UTC+1 schreef mraptor:
Neat .. thank you :

> bc <<b::1>> inbits <<0b00001110::8>>, do: <<b>>
<<0, 0, 0, 0, 1, 1, 1, 0>>

still confusing though :))

Maybe it helps to realize that both the default type of bitstring elements and the way iex displays bitstrings are 8bit integers. In your example you create a 64bit bitstring, not an 8bit bitstring:

iex(1)> <<num::size(8)>> = <<0, 0, 0, 0, 1, 1, 1, 0>>
** (MatchError) no match of right hand side value: <<0, 0, 0, 0, 1, 1, 1, 0>>

iex(2)> <<num::size(64)>> = <<0, 0, 0, 0, 1, 1, 1, 0>>

<<0, 0, 0, 0, 1, 1, 1, 0>>
iex(3)> num
16843008

Bitstrings are just blocks of untyped memory and the bitstring syntax helps to 'parse' these blobs of raw data into meaningful chunks of data.

If you want your example to return an 8bit bitstring, you should write:

iex(4)> bc <<b::1>> inbits <<0b00001110::8>>, do: <<b::1>> # notice the size specifier in the do block
<<14>>

But as you can see this doesn't make much sense as the result is the same as just writing:

iex(5)> <<0b00001110>>
<<14>>

See, iex displays the bitstring as an single 8bit integer, but it's just a matter of representation. These notations all create the exact same bitstring:

<<0b00001110>>
<<0b00001110::8>>
<<14>>
<<0::1, 0::1, 0::1, 0::1, 1::1, 1::1, 1::1, 0::1>>

Hope this helps.




Reply all
Reply to author
Forward
0 new messages