Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

Re^2: Extracting Bit Fields (Again)

by BrowserUk (Patriarch)
on Oct 12, 2005 at 09:32 UTC ( [id://499435]=note: print w/replies, xml ) Need Help??


in reply to Re: Extracting Bit Fields (Again)
in thread Extracting Bit Fields (Again)

Not quite what people above think it does.

perl> printf "%b\n", 162;; 10100010 perl> print unpack 'b1b3b4', 162;; 1 011 0100 perl> print unpack 'B1B3B4', 162;; ## In case of different endian mach +ines. 0 001 0011

Update: The 'Bn' and 'bn' formats unpack bits from bytes, starting from least or most significant bits, but each 'Bn' unpack bits from a whole number of bytes. And always starting at a byte boundary.

So 'b1b3b4' unpacks 1, 3, & 4 bits from each of 3 different bytes. Even if there are more bits in the current byte, and new byte is started when the next Bn is processed.

Vis:

perl> print unpack '(B8)4', pack 'N', 0b11111111_10101010_01010101_000 +00000;; 11111111 10101010 01010101 00000000 perl> print unpack '(B4)4', pack 'N', 0b11111111_10101010_01010101_000 +00000;; 1111 1010 0101 0000

And if n>8, then more than one byte are used for the 'bn', but a new byte is started for the next format.

perl> print unpack '(B16)2', pack 'N', 0b11111111_10101010_01010101_00 +000000;; 1111111110101010 0101010100000000 perl> print unpack '(B12)2', pack 'N', 0b11111111_10101010_01010101_00 +000000;; 111111111010 010101010000

But the significant thing here is that I have packed the input to a binary value.

With pack 'b1b3b4', 162 quite where the input is drawn from is a mystery. the 162 obviously has a binary representation within the scalar, but this would be in the SvIV, and if it were that being decoded you would get this result:

perl> print unpack '(b8)3', pack 'V', 162;; 01000101 00000000 00000000 perl> print unpack 'b1 b3 b4', pack 'V', 162;; 0 000 0000

Ie. The first 1, 3, & 4 bits of the first 3 bytes of the 4-byte binary rep of 162--but you don't.

You get this:

perl> print unpack '(B8)3', 162;; 00110001 00110110 00110010 perl> print unpack 'B1B3B4', 162;; 0 001 0011

which shows where the 1, 011 & 01 come from. The first 1, 3 & 4 bits of three consecutive bytes, but that still leaves the question of where those bytes come from?

And the answer appears to be from the ascii values for 1, 6 & 2. And my guess is that as the scalar into which the bareword 162 is placed has never been used in a numeric context, so it is the string representation that is being unpacked. Hence this gives the same result:

perl> print unpack 'B1B3B4', '162';; 0 001 0011

Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
"Science is about questioning the status quo. Questioning authority".
The "good enough" maybe good enough for the now, and perfection maybe unobtainable, but that should not preclude us from striving for perfection, when time, circumstance or desire allow.

Replies are listed 'Best First'.
Re^3: Extracting Bit Fields (Again)
by ysth (Canon) on Oct 12, 2005 at 22:38 UTC
    Thanks; I had suspected it was using the string "162", but it didn't occur to me it might be applying each B/b to a new byte.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://499435]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others studying the Monastery: (3)
As of 2024-04-16 05:48 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found