I wanted a fast count of the number of set (clear) bits in a string.
I'm getting rather strange results, and I haven't found a clue in
the docs or archives. Here's the code:
use Inline C => q{
char b_set[256];
char b_clear[256];
void bc_init() {
int i, j = 1;
b_set[0] = 0;
while (j < 256) {
for (i = 0; i < j; ++i) {
b_set[i + j] = 1 + b_set[i];
}
j <<= 1;
}
for (i = 0; i < 256; ++i) {
b_clear[i] = b_set[255 - i];
}
}
UV cset(char* pv, UV len) {
UV s = 0;
UV i = len >> 3; # len gives string length in bits
while (i--) {
s += (UV)b_set[*pv++];
}
return s;
}
UV cclear(char* pv, UV len) {
UV s = 0;
UV i = len >> 3; # len gives string length in bits
while (i--) {
s += (UV)b_clear[*pv++];
}
return s;
}
};
I've had various permutations of this, and mostly the results seem
pretty random, then occasionally a particular permutation will give
the right results for one of the cset() or cclear() functions, or
will give the results expected for the other function:
warn sprintf "size: %s, set/clear: %08x/%08x (%s)\n",
$size,
scalar cset($s, $size),
scalar cclear($s, $size),
join '', map sprintf("%02x", ord($_)), split //, $s;
size: 64, set/clear: 00000001/00000000 (fffffffffffffffb)
size: 64, set/clear: 00000004/00000000 (ffffffffffff9eef)
size: 64, set/clear: 0000000a/00000001 (ffffffffffff977f)
size: 64, set/clear: 00000003/00000040 (ffffffffffdfd7ff)
size: 64, set/clear: 00000001/00000040 (fffffffffffff7ff)
(The permutations are minor variations to the functions, not
attempts to declare stuff differently.)
Do I need to do something special to declare static variables?
Or is this perhaps something you can't do at all? (None of the
examples in C-Cookbook, by the way, use a static variable.)
Hugo