This message is one of several periodic postings to DevShed's Perl forum intended to make it easier for Perl programmers to find answers to common questions. The core of this message represents an excerpt from the documentation provided with every Standard Distribution of Perl.

---------------------------------------------
How do I manipulate arrays of bits?

Use pack() and unpack(), or else vec() and the bitwise operations.

For example, this sets $vec to have bit N set if $ints[N] was set:

$vec = '';
foreach(@ints) { vec($vec,$_,1) = 1 }

And here's how, given a vector in $vec, you can get those bits into your
@ints array:

sub bitvec_to_list {
my $vec = shift;
my @ints;
# Find null-byte density then select best algorithm
if ($vec =~ tr/// / length $vec > 0.95) {
use integer;
my $i;
# This method is faster with mostly null-bytes
while($vec =~ /[^]/g ) {
$i = -9 + 8 * pos $vec;
push @ints, $i if vec($vec, ++$i, 1);
push @ints, $i if vec($vec, ++$i, 1);
push @ints, $i if vec($vec, ++$i, 1);
push @ints, $i if vec($vec, ++$i, 1);
push @ints, $i if vec($vec, ++$i, 1);
push @ints, $i if vec($vec, ++$i, 1);
push @ints, $i if vec($vec, ++$i, 1);
push @ints, $i if vec($vec, ++$i, 1);
}
} else {
# This method is a fast general algorithm
use integer;
my $bits = unpack "b*", $vec;
push @ints, 0 if $bits =~ s/^(d)// && $1;
push @ints, pos $bits while($bits =~ /1/g);
}
return @ints;
}

This method gets faster the more sparse the bit vector is. (Courtesy of
Tim Bunce and Winfried Koenig.)

Here's a demo on how to use vec():

# vec demo
$vector = "xffx0fxefxfe";
print "Ilya's string xffx0fxefxfe represents the number ",
unpack("N", $vector), "n";
$is_set = vec($vector, 23, 1);
print "Its 23rd bit is ", $is_set ? "set" : "clear", ".n";
pvec($vector);

set_vec(1,1,1);
set_vec(3,1,1);
set_vec(23,1,1);

set_vec(3,1,3);
set_vec(3,2,3);
set_vec(3,4,3);
set_vec(3,4,7);
set_vec(3,8,3);
set_vec(3,8,7);

set_vec(0,32,17);
set_vec(1,32,17);

sub set_vec {
my ($offset, $width, $value) = @_;
my $vector = '';
vec($vector, $offset, $width) = $value;
print "offset=$offset width=$width value=$valuen";
pvec($vector);
}

sub pvec {
my $vector = shift;
my $bits = unpack("b*", $vector);
my $i = 0;
my $BASE = 8;

print "vector length in bytes: ", length($vector), "n";
@bytes = unpack("A8" x length($vector), $bits);
print "bits are: @bytesnn";
}
---------------------------------------------

Documents such as this have been called "Answers to Frequently Asked Questions" or FAQ for short. They serve to reduce the volume of redundant traffic on this bulletin board by providing quality answers to questions that keep comming up. If you find errors or other problems with these postings please send corrections or comments to the posting email address.


------------------
Written by Anonym0us, inspired by the original PerlFAQ Server.