### Named Bits in a 32-bit integer

by RollyGuy (Chaplain)
 on Jul 31, 2002 at 18:06 UTC Need Help??

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

I'm using a SWIG interface to C++ on one of my projects at work. On the C++ side, we have a 32-bit integer where the different bits represent different (named) settings. We're using perl as the interface to C++ and would like an easy way to set (and unset) these bits using named constants. In C++ there are Enumerated values that give me that functionality. Is there anything like that in perl?

Is there a good way to do this?

Replies are listed 'Best First'.
Re: Named Bits in a 32-bit integer
by RMGir (Prior) on Jul 31, 2002 at 18:33 UTC
Sure, the constant pragma.
```use constant BIT0 => 0;
use constant BIT1 => 1;
use constant BIT2 => 2;
use constant BIT3 => 4;
#...
That's pretty verbose, though... You could just use a hash, and do
```my %bitNames = (
BIT0 => 0,
BIT1 => 1,
BIT2 => 2,
BIT3 => 4,
BIT4 => 8,
#...
);
Of course, you can substitute your more meaningful names for BIT0..BITn...

That handles naming the bits; you could use the vec built-in function to set them, like this:

```my \$flag=0; # or value from your api
vec(\$flag, \$bitNames{BIT0}, 1)=\$newBit;
# you can also use vec to retrieve the old bit values:
print "Value at position BIT3 is:",vec(\$flag, \$bitNames{BIT3},1),"\n";

--
Mike
EDIT: Added part about vec; I'd only covered naming the bits, and forgotten the other part...
Re: Named Bits in a 32-bit integer
by BronzeWing (Monk) on Jul 31, 2002 at 19:27 UTC

I think the simplest way to do it is with the &, |, ^, and ~ operators. An example:

```#!/usr/bin/perl
use warnings;
use strict;
use constant EXECUTE => 1;
use constant WRITE => 2;

my \$Permissions = 0;
\$Permissions |= WRITE; # Set WRITE to true
\$Permissions ^= EXECUTE; # Toggle EXECUTE
print \$Permissions, "\n";

Prints "3" (that's WRITE and EXECUTE).
Is this what you were looking for?

-BronzeWing

Update:
Oops! I completely forgot getting the info back out again. To check the status of a bit:

```if (\$Permissions & READ) {
} else {
}

Just like that.

The Secret to Fortune Cookies in One Line
print join("... in bed", `fortune fortunes` =~ m/^(.*)(\.|\?|\!)\$/), "\n";

Re: Named Bits in a 32-bit integer
by fglock (Vicar) on Jul 31, 2002 at 19:40 UTC

I'm still thinking about it, but I think this is more or less what you need (there might be a module that does this on CPAN; "enum" comes pretty close) :

```use strict;

package Bit;
use Tie::Scalar;

sub TIESCALAR {
my (\$self) = bless {}, shift;
\$self->{ref} = shift;
\$self->{bit} = 0;
while ( !(\$tmp & 1)) {
\$tmp >>= 1;
\$self->{bit} ++;
}
return \$self;
}

sub FETCH {
my \$self = shift;
return ( \${\$self->{ref}} & \$self->{mask} ) >> \$self->{bit} ;
}

sub STORE {
my \$self = shift;
my \$value = shift;
\${\$self->{ref}} |= \$self->{mask} & (\$value << \$self->{bit});
}

#---------------------

my \$bits = 0;     # a "n-bits" variable
tie my \$a, 'Bit', \\$bits, 0x07;  # bits 0..3 are \$a
tie my \$b, 'Bit', \\$bits, 0x70;  # bits 4..7 are \$b

\$a = 1;
print "\$bits\n";   # 1
\$b = 1;
print "\$bits\n";   # 17
\$a = 0;
print "\$bits\n";   # 16

update: - The "bit" parameter is calculated by TIESCALAR.
- Using "vec" instead of bitwise operations is a good idea.

Re: Named Bits in a 32-bit integer
by hiseldl (Priest) on Jul 31, 2002 at 18:40 UTC
Assuming perl -P works on your system, you could define macros. Here is a short example:
```#!/usr/bin/perl -P

# set this to the bit masks
#define ONE 1
#define TWO 2
#define THREE 3
#define FOUR 4

print "bitwise AND (ONE & FOUR)=", ONE & FOUR, "\n";
print "bitwise AND (ONE & THREE)=", ONE & THREE, "\n";
then running the script will produce:
```\$ ./script.pl
bitwise AND (ONE & FOUR)=0
bitwise AND (ONE & THREE)=1
```

If perl -P gives an error where it can't find cpp, you can probably copy the one from your gcc dist into a directory into your path.

--
hiseldl

Re: Named Bits in a 32-bit integer
by perrin (Chancellor) on Jul 31, 2002 at 18:42 UTC

Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://186551]
Approved by jeffa
Front-paged by jeffa
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others perusing the Monastery: (6)
As of 2022-08-09 01:27 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?

No recent polls found

Notices?