Reputation: 644
Consider this example:
#!/usr/bin/env perl
my $vec0;
# set the first bit of vec0 to false
vec($vec0, 0, 1) = 0;
print "vec0 is " . length($vec0) . " bytes long\n";
if ($vec0) {
# what
print "vec0 is True!\n";
}
A vec
used in evaluation seems to (almost) always be True - this is because a vec
is really a string, and so $vec0
is a string containing "\0" which is not False according to Perl: only strings "" and "0" are False.
(aside: this is False, despite being non-zero:
vec($vec0, 5, 1) = 1;
vec($vec0, 4, 1) = 1;
because 0x30 is the ASCII code for 0
)
Fine: what is the "correct" way to check for an "empty" vector (i.e. all bits set to 0)? Count bits with unpack
, regex test m/^\0*$/
, "normalize" all vectors by chopping empty bytes off the end? This seems like it should be a solved problem... and why does Perl not treat vec
magically for true/false?
Upvotes: 2
Views: 107
Reputation: 386541
The following is probably the fastest approach without external C code:
$vec0 !~ tr/\x01-\xFF// # True if "empty".
$vec0 =~ tr/\x01-\xFF// # True if not "empty".
Upvotes: 2
Reputation: 66964
To check that
All bits in the vector are unset (0)
can convert it to a (bit)string with my $bits = unpack("b*", $vector)
and then in numeric context that will be equal to zero ($bits == 0)
if all bits are unset. So
if ( unpack("b*", $vec0) == 0 ) { say "All bits zero" }
This is a shorthand of checking that no bits are set, ( unpack("b*", $vec0) | 0 ) == 0
.
I don't think that vec
has any "magical" way of checking for this.
Upvotes: 3
Reputation: 52579
If you're using fixed-width vectors, you can create another one of the appropriate length that's all-zeros and compare it with ones you want to test.
my $zero_vec = pack "C*", (0) x $length_in_bytes;
# ...
if ($vec0 ne $zero_vec) {
print "vec0 is True!\n";
}
I also found an old module on CPAN, String::BitCount
, that counts the number of set bits in a string:
use String::BitCount;
# ...
if (BitCount($vec0)) {
print "vec0 is True!\n";
}
or maybe a regular expression:
if ($vec0 !~ m/\A\x00+\z/) {
print "vec0 is True!\n";
}
Upvotes: 2