【发布时间】:2018-07-26 22:26:16
【问题描述】:
Perl 非常擅长处理位串/向量。设置位很简单
vec($bit_string, 123, 1) = 1;
获取设置位的数量非常快
$count = unpack("%32b*", $bit_string);
但是,如果您将值设置为高于 2_147_483_639,您的计数将自动归零,而不会出现任何明显的警告或错误。
有没有办法解决这个问题?
以下代码演示了问题
#!/usr/bin/env perl
# create a string to use as our bit vector
my $bit_string = undef;
# set bits a position 10 and 2_000_000_000
# and the apparently last valid integer position 2_147_483_639
vec($bit_string, 10, 1) = 1;
vec($bit_string, 2_000_000_000, 1) = 1;
vec($bit_string, 2_147_483_639, 1) = 1;
# get a count of the bits which are set
my $bit_count = unpack("%32b*", $bit_string);
print("Bits set in bit string: $bit_count\n");
## Bits set in bit string: 3
# check the bits at positions 10, 11, 2_000_000_000, 2_147_483_639
for my $position (10,11,2_000_000_000, 2_147_483_639) {
my $bit_value = vec($bit_string, $position, 1);
print("Bit at $position is $bit_value\n");
}
## Bit at 10 is 1
## Bit at 11 is 0
## Bit at 2000000000 is 1
## Bit at 2147483639 is 1
# Adding the next highest bit, 2_147_483_640, causes the count to become 0
# with no complaint, error or warning
vec($bit_string, 2_147_483_640, 1) = 1;
$bit_count = unpack("%32b*", $bit_string);
print("Bits set in bit string after setting bit 2_147_483_640: $bit_count\n");
## Bits set in bit string after setting bit 2_147_483_640: 0
# But the bits are still actually set
for my $position (10, 2_000_000_000, 2_147_483_639, 2_147_483_640) {
my $bit_value = vec($bit_string, $position, 1);
print("Bit at $position is $bit_value\n");
}
## Bit at 10 is 1
## Bit at 2000000000 is 1
## Bit at 2147483639 is 1
## Bit at 2147483640 is 1
# Set even higher bits
vec($bit_string, 3_000_000_000, 1) = 1;
vec($bit_string, 4_000_000_000, 1) = 1;
# verify these are also set
for my $position (3_000_000_000, 4_000_000_000) {
my $bit_value = vec($bit_string, $position, 1);
print("Bit at $position is $bit_value\n");
}
## Bit at 3000000000 is 1
## Bit at 4000000000 is 1
【问题讨论】:
-
你有一个 20 亿位的位图?!
-
经常。 unpack("%32b*") 在计算设置位时有多快真是太疯狂了。您可以通过位向量上的位操作来做一些令人惊奇的事情。