Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things


by rir (Vicar)
on Jul 28, 2006 at 21:14 UTC ( #564462=perlquestion: print w/replies, xml ) Need Help??
rir has asked for the wisdom of the Perl Monks concerning the following question:

I have looked around and found little on how to flip bits in Perl. Should I be thinking bit-strings and vec or integers and masks as in the C style?

My data comes in sets of 9 booleans which are named "1" through "9". The operations required:

  • have name, clear bit
  • have name(s), set bit(s)
  • get count of set bits
  • have one set bit, get its name
  • have multiple set bits, get names (debugging only)
  • bit-wise logical ops, OR, AND, ...
This is off the cuff sample code:
$state = $prev | $curr | $next; if ( FULL == count_bits( $state ) ) { # unset these bits in other blocks for my $block ( @grid ){ $block &= ~$state; # cache block if appropriate if ( TERMINAL == count_bits( $block) ) { push @feed_thru, $block; }elsif ( FULL == count_bits( $block ) ) { push @propagate, $block; } } }
Be well, rir

Replies are listed 'Best First'.
Re: bit-wise
by Zaxo (Archbishop) on Jul 28, 2006 at 21:52 UTC

    I think that I would splurge a little on memory and use a hash (or maybe an array if the names are really '1' .. '9'). All the operations you want are easy and straightforward with a hash:

    my %state; @state{1..9}=();
    1. have name, clear bit
      $state{$name} = undef;
    2. have name(s), set bit(s)
      @state{@names} = (1) x @names;
    3. get count of set bits
      my $count = grep {$_} values %state;
    4. have one set bit, get its name
      my $setname = (grep {$state{$_}} keys %state)[0];
    5. have multiple set bits, get names (debugging only)
      my @setnames = grep {$state{$_}} keys %state;
    6. bit-wise logical ops, OR, AND, ...
      # same as ordinary perl print $foo if $state{$one} && $state{$tother};
    A small hash like this isn't going to break the bank, and the perl operations to maintain it are much simpler than bit-twiddling.

    Fixed typo in #2, thanks blokhead++

    After Compline,

Re: bit-wise
by liverpole (Monsignor) on Jul 28, 2006 at 21:28 UTC
    Hi rir,

    For my own tastes, I would use integers and masks, in the "C" style.  Of course, my background is in "C", so you might call me biased.

    For example, here's a simple example of clear_bit and set_bit using a mask and a bit index:

    #!/usr/bin/perl -w # Strict use strict; use warnings; # Test code my $mask = 0b11001011; clear_bit($mask, 1); clear_bit($mask, 2); clear_bit($mask, 3); clear_bit($mask, 4); $mask = 0b11001000; set_bit($mask, 1); set_bit($mask, 2); set_bit($mask, 3); set_bit($mask, 4); # Subroutines sub clear_bit { my ($mask, $bit_index) = @_; printf "TFD> mask 0b%08lb\n", $mask; $mask &= ~(1 << ($bit_index - 1)); printf "TFD> mask 0b%08lb\n\n", $mask; } sub set_bit { my ($mask, $bit_index) = @_; printf "TFD> mask 0b%08lb\n", $mask; $mask |= (1 << ($bit_index - 1)); printf "TFD> mask 0b%08lb\n\n", $mask; }

    The lines containing "TFD" are temporary debugging statements which can be removed once you've verified that the code is doing what you want.

    Of course, if you want to use names in place of the bit_index, you could either pass the string (character) containing the name "1" - "9", and convert it back to an integer, or (where necessary) you could pass a hash containing the names (bit indices) you wish to operate on.

    I'm sure you can write the rest of the subroutines, if this is the route you decide to go.  (But feel free to ask if you need more help or suggestions!)

Re: bit-wise
by imp (Priest) on Jul 28, 2006 at 23:47 UTC
    I can't get to CPAN at the moment to check for modules that handle bits efficiently, but this node has some good advice on the topic: Handling bits in Perl

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://564462]
Approved by Hue-Bond
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others having an uproarious good time at the Monastery: (6)
As of 2018-01-24 08:25 GMT
Find Nodes?
    Voting Booth?
    How did you see in the new year?

    Results (256 votes). Check out past polls.