Skip to content

Instantly share code, notes, and snippets.

@jprupp
Created March 15, 2012 15:32
Show Gist options
  • Save jprupp/2044818 to your computer and use it in GitHub Desktop.
Save jprupp/2044818 to your computer and use it in GitHub Desktop.
popcount() in Perl
#!/usr/bin/env perl
use strict;
use warnings;
use Test::More;
use List::Util qw(reduce);
my @masks = map {
my $group_bin = 0 x $_ . 1 x $_;
my $bin_length = $_ * 2;
my $mask_bin = $group_bin x ( 32 / $bin_length );
unpack 'N', pack 'B32', $mask_bin;
} 1, 2, 4, 8, 16;
sub popcount($) {
my $num = shift;
maskshift( $num, 0, 1 );
}
sub maskshift {
my ( $num, $mask_index, $length ) = @_;
my $mask = $masks[$mask_index];
my $sum = ( $num & $mask ) + ( $num >> $length & $mask );
if ( $mask_index < $#masks ) {
maskshift( $sum, $mask_index + 1, $length * 2 );
} else {
$sum;
}
}
is( popcount 38164, 6, "Population count correct for 38164" );
is( popcount 65535, 16, "Population count correct for 65535" );
is( popcount 65536, 1, "Population count correct for 65536" );
my @array = map { int rand 65536 } 1 .. 10000;
my $popct = reduce { our $a + our $b } map { popcount $_ } @array;
ok( defined $popct, "Counted population of 10000 random ints: $popct" );
done_testing();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment