Gerard has asked for the wisdom of the Perl Monks concerning the following question:

Confusion, any help to clarify, much appreciated: Here is a sample example of what I am trying to do
use strict; my $char = "~"; my $temp = vec($char, 0, 8); my @charBits = split(//, unpack("b8", $temp)); print $temp . "\n"; foreach (@charBits){ print $_; }
what I was expecting to see was something like:
126 01111110
but instead I got:
126 10001100
I am obviously missing something vital.
Please help.

Regards, Gerard

Replies are listed 'Best First'.
Re: using vec() and unpack()
by antirice (Priest) on Aug 16, 2003 at 03:17 UTC

    Hmm...you're absolutely right. However, let's take a look at what it is printing out.

    With your unpack, you are specifying b which means that the left-most bit is least significant. So what does 10001100 become? 49. What's 49? It is the ascii code for 1. If you change your unpack to "b*", @charBits contains 24 elements and looks like: 100011000100110001101100. Taken in 8 bit chunks, it turns out to be 49, 50, 54 (the ascii codes for 1, 2 and 6).

    Please remember that unpack thinks whatever you give it is a string. To fix your problem, all you need to do is first pack your 126 as an integer like so: my @charBits = split(//, unpack('b8', pack("S",$temp)));. Now the code should works as expected (it should print 01111110). Please check out perlpacktut for more information.

    Hope this helps.

    antirice    
    The first rule of Perl club is - use Perl
    The
    ith rule of Perl club is - follow rule i - 1 for i > 1

Re: using vec() and unpack()
by jmcnamara (Monsignor) on Aug 16, 2003 at 08:41 UTC

    Another way to do it is to use ord and printf*:
    #!/usr/bin/perl -wl use strict; my $char = '~'; print ord $char; printf "%08b\n", ord $char; __END__ Prints: 126 01111110

    * The "%b" format is only available with perl5.6 or later.

    --
    John.

Re: using vec() and unpack()
by graff (Chancellor) on Aug 16, 2003 at 03:21 UTC
    Apparently what you want instead of this:
    my @charBits = split(//, unpack("b8", $temp));
    is rather something like this:
    my @charBits = split(//, unpack("b8", $char));
    But apart from that, you should test some value other than the tilde character, and make sure you figure out whether you want to use "b8" or "B8" as the formatting string for the unpack call.

    As for doing 'unpack("b8", $temp)', it's hard for me to figure out what that actually does. Note that you get more output if you use "b*" there -- but that didn't help me at all, I still don't know what it's doing.

      Thanks, after reading antirice's reply above, I ended up with something very similar to your suggestion:
       @charBits = split(//, unpack("b8", @chars[$currentChar])); which does the trick quite nicely.
      Thanks again
      Gerard