Output of Erlang bit packing - erlang

I am not able to understand bit packing in erlang.
Suppose:
R=4, G=6 and B=8
then why is the output like this:
<< R:5,G:5,B:6 >>
output: <<33,136>>.
I don't get it. Can anyone please explain?

<< R:5,G:5,B:6 >>
This record we allocate 5,5 and 6 bits, and the result is a 2-byte binary sequence. To better understand why this happens, start the reverse conversion. Transform numbers 33 and 136 in binary form:
integer_to_list(33,2).
integer_to_list(136,2).
"100001"
"10001000"
We get the following lines. Since each segment of the binary sequence is a multiple of 8, supplement the presentation of 33 zeros to the left.
L2=lists:append("00",lists:append(integer_to_list(33,2),integer_to_list(136,2))).
"0010000110001000"
Proceed to the decoding of. The third argument indicates the number of bits
V1 = list_to_integer(lists:sublist(L2,5),2).
V2 = list_to_integer(lists:sublist(L2,6,5),2).
V3 = list_to_integer(lists:sublist(L2,11,6),2).
4
6
8
Sorry for my English,hope I explained clearly.

Related

Length and size of strings in Elixir / Erlang needs explanation

Can someone explain why s is a string with 4096 chars
iex(9)> s = String.duplicate("x", 4096)
... lots of "x"
iex(10)> String.length(s)
4096
but its memory size are a few 6 words?
iex(11)> :erts_debug.size(s)
6 # WHAT?!
And why s2 is a much shorter string than s
iex(13)> s2 = "1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20"
"1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20"
iex(14)> String.length(s)
50
but its size has more 3 words than s?
iex(15)> :erts_debug.size(s2)
9 # WHAT!?
And why does the size of these strings does not match their lengths?
Thanks
First clue why this is showing that values can be found in this question. Quoting size/1 docs:
%% size(Term)
%% Returns the size of Term in actual heap words. Shared subterms are
%% counted once. Example: If A = [a,b], B =[A,A] then size(B) returns 8,
%% while flat_size(B) returns 12.
Second clue can be found in Erlang documentation about bitstrings implementation.
So in the first case the string is too big to fit on heap alone, so it uses refc binaries which are stored on stack and on heap there is only pointer to given binary.
In second case string is shorter than 64 bytes and it uses heap binaries which is just array of bytes stored directly in on the heap, so that gives us 8 bytes per word (64-bit) * 9 = 72 and when we check documentation about exact memory overhead in VM we see that Erlang uses 3..6 words per binary + data, where data can be shared.

Getting the size in bytes of an arbitrary integer

Given an integer, 98749287 say, is there some built-in/libray function, either Erlang or Elixir, for getting the size in bytes?
To clarify, the minimum number of bytes used to represent the number in binary.
Seems simple, and have written a function using the "division by base" method and then counting bits, but after some hrs of searching docs havent found anything for what would seem useful to have.
If you have an unsigned integer, you can use the following snippet:
byte_size(binary:encode_unsigned(Integer))
Example:
1> byte_size(binary:encode_unsigned(3)).
1
2> byte_size(binary:encode_unsigned(256)).
2
3> byte_size(binary:encode_unsigned(98749287)).
4
Try this expression:
Value = (... your input ...),
NumBytes = size(integer_to_binary(Value, 2) + 7) div 8.
Reference: http://www.erlang.org/doc/man/erlang.html#integer_to_binary-2

Bit Syntax and Binary Representation in Erlang

I'm trying to get my head around the Bit Syntax in Erlang and I'm having some trouble understand how this works:
Red = 10.
Green = 61.
Blue = 20.
Color = << Red:5, Green:6, Blue:5 >> .
I've seen this example in the Software for a concurrent world by Joe Armstrong second edition and this code will
create a 16 bit memory area containing a single RGB triplet.
My question is how can 3 bytes be packed in a 16-bit memory area?. I'm not familiar whatsoever with bit shifting and I wasn't able to find anything relevant to this subject referring to erlang as well. My understand so far is that the segment is made up of 16 parts and that Red occupies 5, green 6 and blue 5 however I'm note sure how this is even possible.
Given that
61 = 0011011000110001
which alone is 16 bits how is this packaging possible?
To start with, 61 is only equal to 00110110 00110001 if you store it as two ASCII digits. When written in binary, 61 is 111101.
Note that the binary representation requires six binary digits, or six "bits" for short. That's what we're taking advantage of in this line:
Color = << Red:5, Green:6, Blue:5 >> .
We're using 5 bits for the red value, 6 bits for the green value, and 5 bits for the blue value, for a total of 16 bits. This works since the red value and the blue value are both less than 32 (since 31 is the largest number that can be represented with 5 bits), and the green value is less than 64 (since 63 is the largest number that can be represented with 6 bits).
The complete value is 01010 111101 10100 (three segments for red, green and blue), or if we split it into two bytes, 01010111 10110100.

Irregularities in Gforth's conversion to doubles

I'm fairly confused about how the s>d and d>s functions work in Forth.
From what I've read, typing 16.0 will put 160 0 on the stack (since it takes up two cells) and d. will show 160.
Now, if I enter 16 s>d I would expect the stack to be 160 0 and d. to show 160 like in the previous example. However, the stack is 16 0 and d. is 16.
Am I entering doubles incorrectly? Is s>d not as simple as "convert a single celled value into a double celled value? Is there any reason for this irregularity? Any clues would be much appreciated.
Gforth interpets all of these the same: 1.60, 16.0, and 160., i.e. 160 converted to a double number. Whereas 16 s>d converts 16 to a double number.
ANS Forth only mandates that when the text interpreter processes a number that is immediately followed by a decimal point and is not found as a definition name, the text interpreter shall convert it to a double-cell number. But Gforth goes beoynd that: http://www.complang.tuwien.ac.at/forth/gforth/Docs-html/Number-Conversion.html#Number-Conversion

Erlang Bit Syntax: How does it knows that it's 3 components?

I've been reading book about Erlang to evaluate if it's suitable for my project, and struble upon the bit syntax part of Learn You Some Erlang for Great Book.
Simply put, here's the code:
1> Color = 16#F09A29.
15768105
2> Pixel = <<Color:24>>.
<<240,154,41>>
What's confusing me is this: the Color variable is 24 bits, but how could Erlang knows that it has to divide the variable (in line 2) into three segments? How is the rule read?
I've tried to read the rest of the chapter, but it's getting more and more confusing me, because I don't understand how it divides the numbers. Could you please explain how the bit syntax works? How can it know that it's 3 segments, and how can it becomes <<154, 41>> when I do this:
1> Color = 16#F09A29.
15768105
2> Pixel = <<Color:16>>.
<<154,41>>
Thanks before.
Color = 16#F09A29 is an integer that can be written as 15768105 in decimal representation, as well as
00000000111100001001101000101001
in binary representation.
when you define a binary Pixel = << Color:24 >>. it just means that you say "Match the 24 less significant bits of Color with the binary Pixel". so Pixel is bounded to
111100001001101000101001,
without any split! when the shell prints it out, it does it byte per byte in decimal representation that is:
11110000 = 15*16 = 240, 10011010 = 9 * 16 + 10 = 154, 00101001 = 2 *
16 + 9 = 41 => << 240,154,41 >>
in the same way, when you define Pixel = << Color:16 >>, it takes only the 16 less significant bits and assign them to the binary =
1001101000101001,
which is printed 10011010 =
9 * 16 + 10 = 154, 00101001 = 2 * 16 + 9 = 41 => << 154,41 >>.
In the case of <> the binary equals now
100001001101000101001
( the 21 less significant bits) and when the shell prints them, it starts as usual, dividing the binary into bytes so
10000100 = 8*16 + 4 = 132, 11010001 = 13 *16 +1 = 209, as it remains only 5 bits 01001, the last chunk of data is printed 5:9 to tell us that the size of the last value is not 8 bits = 1 byte as usual, but only 5 bits =>
<< 132,209,5:9 >>.
The nice thing with binaries, is that you can "decode" them using size specification (maybe it is more clear with the example bellow).
(exec#WXFRB1824L)43> Co=16#F09A29.
15768105
(exec#WXFRB1824L)44> Pi = <<Co:24>>.
<<240,154,41>>
(exec#WXFRB1824L)45> <<R:8,V:8,B:8>> = Pi.
<<240,154,41>>
(exec#WXFRB1824L)46> R.
240
Erlang doesn't really "divide" anything. Binaries are just continuous blocks of data. It's the default human-readable representation that is printed by REPL is a comma-separated list of byte values.
It's just showing the 8-bit bytes that make up the binary. You're telling it to get 24 bits, and it's rendering them in the numeric representation (0-255) of each individual byte.

Resources