# Re: FAQ 4.53 How do I manipulate arrays of bits?

#### Do you have a question? Post it now! No Registration Necessary.  Now with pictures!

•  Subject
• Author
• Posted on
<snip>

<snip>

IMHO the above sentence is wrong.
It'd rather say
'For example, this sets \$vec to have bit N set if N is element of
@ints'.

my @ints = ();
\$ints[5] = 1;
\$ints[0] = 1;
\$ints[2] = 1;
\$ints[4] = 1;

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

print unpack('b*', \$vec), "\n";

11000000
(plus warnings about values being uninitialized)

my @ints = (5,0,2,4);
my \$vec = '';

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

print unpack('b*', \$vec), "\n";

10101100

Steffen

## Re: FAQ 4.53 How do I manipulate arrays of bits?

In article

Indeed it is.  Thanks for noticing it. :)

Here's my replacement:

For example, you don't have to store individual bits in an array
(which would mean that you're wasting a lot of space). To convert an
array of bits to a string, use C<vec()> to set the right bits. This
sets C<\$vec> to have bit N set only if C<\$ints[N]> was set:

@ints = (...); # array of bits, e.g. ( 1, 0, 0, 1, 1, 0 ... )
\$vec = '';
foreach(@ints) {
vec(\$vec,\$_,1) = 1 if \$_;
}

The string C<\$vec> only takes up as many bits as it needs. For
bytes to store them (not counting the scalar variable overhead).

## Re: FAQ 4.53 How do I manipulate arrays of bits?

bdf> In article

>> <snip>
>> >     For example, this sets \$vec to have bit N set if \$ints[N] was set:
>> >
>> >             \$vec = '';
>> >             foreach(@ints) { vec(\$vec,\$_,1) = 1 }
>> >
>> <snip>
>>
>> IMHO the above sentence is wrong.

and the code is wrong too.

my @ints = ( 1, 0, 0, 1, 1, 0 ) ;
my \$vec = '';
foreach(@ints) {
vec(\$vec,\$_,1) = 1 if \$_;
}

print  join( '', unpack 'B*', \$vec ), "\n" ;

foreach(0 .. \$#ints) {
vec(\$vec,\$_,1) = \$ints[\$_];
}

print  join( '', unpack 'B*', \$vec ), "\n" ;

output:
00000010
00011001

the FAQ loop never changes the offset arg to vec so it twiddles the same
bit over and over.

in fact given a list of bit values, pack is the best answer for making a
bit vector. vec is better for random access of bit fields (and it sucks
because of its requirement for the field size being a power of
2). Bit::Vector is a very good module (speedy since it is in XS) for all
sorts of bit stuff.

uri

--
Uri Guttman  ------  uri@stemsystems.com  --------  http://www.sysarch.com --
-----  Perl Architecture, Development, Training, Support, Code Review  ------
-----------  Search or Offer Perl Jobs  ----- http://jobs.perl.org ---------
---------  Gourmet Hot Cocoa Mix  ----  http://bestfriendscocoa.com ---------

## Re: FAQ 4.53 How do I manipulate arrays of bits?

That depends on how you see it.
The use of vec() as a replacement for pack() on a ready list of bits
has never occurred to me.

Hence my 2nd example above with some distinct bit indices specified:
my @ints = (5,0,2,4);

For this case the FAQ loop works alright.

ACK
Beside the ubiquitous example for the use of vec() with select() I
only ever found an application in creating symbol distribution
patterns for sudoku solvers.
And Bit::Vector would most certainly have proven more adequate for the

Steffen

## Re: FAQ 4.53 How do I manipulate arrays of bits?

damn it. I had it right in my tests then didn't update the text.  I've
committed the fix.

Thanks,

## Re: FAQ 4.53 How do I manipulate arrays of bits?

>>
bdf> In article
>>
>> >> <snip>
>> >> >     For example, this sets \$vec to have bit N set if \$ints[N] was set:
>> >> >
>> >> >             \$vec = '';
>> >> >             foreach(@ints) { vec(\$vec,\$_,1) = 1 }
>> >>
>> and the code is wrong too.

s> That depends on how you see it.

huh? the code doesn't do what the comment says. and even if the comment
were fixes, the example has bit offsets of only 1 and 0 so it will never
touch any bits other than 1 (the second bit). it would be hard to find a
use for that logic.

s> The use of vec() as a replacement for pack() on a ready list of bits
s> has never occurred to me.

s> Hence my 2nd example above with some distinct bit indices specified:
s> my @ints = (5,0,2,4);

but the CODE didn't have any indices other than 1 and 0. so it was
useless as an example and it didn't even agree with the text. the whole
thing is wrong.

s> ACK
s> Beside the ubiquitous example for the use of vec() with select() I
s> only ever found an application in creating symbol distribution
s> patterns for sudoku solvers.

and even using it for select is not a good example since IO::Select is
so much easier to use. only people like me who know select very well
(over 20 years of coding with it in c and perl) use it directly.

s> And Bit::Vector would most certainly have proven more adequate for the

that should be mentioned in the FAQ for sure. vec() is a very wimpy
function in general. its word size is fixed to a power of two which is
very bizarre. pack/unpack do much more useful things for single bits and
4 bit (nibble) lengths. bit::vector does all the really useful things
you want and faster (and with any word size). vec() in general should be
deprecated IMO. i never teach it in my classes and would recommend other

uri

--
Uri Guttman  ------  uri@stemsystems.com  --------  http://www.sysarch.com --
-----  Perl Architecture, Development, Training, Support, Code Review  ------
-----------  Search or Offer Perl Jobs  ----- http://jobs.perl.org ---------
---------  Gourmet Hot Cocoa Mix  ----  http://bestfriendscocoa.com ---------

## Re: FAQ 4.53 How do I manipulate arrays of bits?

wrote:

Surely true, but so crankish sounding...

Michele
--
->(map substr
((\$a||=join'',map--\$|x\$_,(unpack'w',unpack'u','G^<R<Y]*YB='
.'KYU;*EVH[.FHF2W+#"\Z*5TI/ER<Z`S(G.DZZ9OX0Z')=~/./g)x2,\$_,
256),7,249);s/[^\w,]/ /g;\$ \=/^J/?\$/:"\r";print,redo}#JAPH,

## Re: FAQ 4.53 How do I manipulate arrays of bits?

MD> wrote:

>> and even using it for select is not a good example since IO::Select is
>> so much easier to use. only people like me who know select very well
>> (over 20 years of coding with it in c and perl) use it directly.

MD> Surely true, but so crankish sounding...

you would be cranky if you had to write event loops with the select api
(in any language). if you go further back it used to only support 32
handles as they used a single word for the bit maps! sysv created the
much better poll api and more recent kernels have much improved apis and
speed. and there is a new perl module called EV that can use any of
several kernel apis for select and friends. libevent (a c lib) can also
do that. so there is little reason to delve into raw select except for
those crazy or experienced enough. perl exposed select it its own style
because when larry wrote perl it was the only common api for this.

uri

--
Uri Guttman  ------  uri@stemsystems.com  --------  http://www.sysarch.com --
-----  Perl Architecture, Development, Training, Support, Code Review  ------
-----------  Search or Offer Perl Jobs  ----- http://jobs.perl.org ---------
---------  Gourmet Hot Cocoa Mix  ----  http://bestfriendscocoa.com ---------

## Re: FAQ 4.53 How do I manipulate arrays of bits?

I don't remember that and my memory of select also goes back about 20
years. In fact the first version of select I do remember didn't have any
arbitrary limit (you passed in pointers to unsigned int and a count)
unlike the stupid fd_sets.

hp

## Re: FAQ 4.53 How do I manipulate arrays of bits?

>>
MD> wrote:
>>
>> >> and even using it for select is not a good example since IO::Select is
>> >> so much easier to use. only people like me who know select very well
>> >> (over 20 years of coding with it in c and perl) use it directly.
>>
MD> Surely true, but so crankish sounding...
>>
>> you would be cranky if you had to write event loops with the select api
>> (in any language). if you go further back it used to only support 32
>> handles as they used a single word for the bit maps!

PJH> I don't remember that and my memory of select also goes back about 20
PJH> years. In fact the first version of select I do remember didn't have any
PJH> arbitrary limit (you passed in pointers to unsigned int and a count)
PJH> unlike the stupid fd_sets.

that version took a pointer to an array of ints and the count specified
the length of the array. i don't recall using the oldest version (i
started on bsd 4.1) which supported only a single int of handle mask
bits. this was an obvious limitation that they didn't plan for when the
sockets api was first created in early BSD (i think in the 2.x
versions). remember, back then the whole idea of a multisocketed server
was novel and no one know how important it would become. it was one of
the first available OS's to support ethernet and tcp/IP. others
supported them but were proprietary or experimental.

i am not sure how i would google for old bsd api docs. i leave that as
an exercise to the reader :)

uri

--
Uri Guttman  ------  uri@stemsystems.com  --------  http://www.sysarch.com --
-----  Perl Architecture, Development, Training, Support, Code Review  ------
-----------  Search or Offer Perl Jobs  ----- http://jobs.perl.org ---------
---------  Gourmet Hot Cocoa Mix  ----  http://bestfriendscocoa.com ---------

## Re: FAQ 4.53 How do I manipulate arrays of bits?

In my initial reply to the FAQ I've given a working example with
exactly the code you cited above.
It all depends on what the content of @ints is. In my eyes, not the
code is erroneous, but only the descriptive sentence.
It might be that someone has amended a formerly correct example. Maybe
someone with pack() on his mind.

The CODE didn't show the array to have only 1 and 0. It was only the
sentence that implied it. And the CODE implied that @ints should
contain something else.
As I said, it depends on your point of view.

steffen