Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

Re: Efficient bit counting with a twist.

by trizen (Friar)
on Jan 28, 2013 at 13:45 UTC ( #1015704=note: print w/ replies, xml ) Need Help??


in reply to Efficient bit counting with a twist.

my $c = unpack("%32b*", pack "B$p", unpack "B$p", $v);

Note that $p start with zero.


Comment on Re: Efficient bit counting with a twist.
Select or Download Code
Re^2: Efficient bit counting with a twist.
by BrowserUk (Pope) on Jan 28, 2013 at 14:00 UTC

    Note that that sequence of unpack/pack/unpack achieves exactly the same thing as AnomalousMonk's unpack "%32b$p".

    But the latter avoids turning a 500MB string into a 4 billion element list of 1s and 0s before converting it back to the 500MB string; which is what that sequence of unpack/pack/unpack does.


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      Maybe I'm crazy, but this doesn't seem to work:
      #!/usr/bin/perl use strict; use warnings; my $mask = hex($ARGV[0]); my $setbits = unpack("%32b*", $mask); printf("0x%x has %d set\n", $mask, $setbits);

      Then I run it:
      ./bittest 0xff
      0xff has 11 set

      Or worse:
      ./bittest 0x1001
      0x1001 has 14 set

      Even the simple case:
      ./bittest 0
      0x0 has 2 set

      What is going on here?

        What is going on here?

        I tweaked your code by adding a couple of extra print statements:

        my $mask = hex($ARGV[0]); print $mask; print unpack 'H*', $mask; my $setbits = unpack("%32b*", $mask); printf("0x%x has %d set", $mask, $setbits);

        And when I run it I get this output:

        C:\test>junk 0xff 255 ## 3 bytes 323535 ## 6 nybbles with bit patterns 0011 0010 0011 0101 0011 0101 0xff has 11 set

        hex converts the string '0xff' to a number which you store in $mask;

        unpack expects a string, so perl helpfully converts the number stored in $mask to a string in the default decimal representation '255'.

        You are counting the bits in that 3 byte string.

        To count the bits in the number, you need to tell perl that you want the binary representation of that number:

        #! perl -slw use strict; my $mask = hex($ARGV[0]); print $mask; print unpack 'H*', pack 'C', $mask; my $setbits = unpack("%32b*", pack 'C', $mask ); printf("0x%x has %d set", $mask, $setbits); __END__ C:\test>junk 0xff 255 ff 0xff has 8 set

        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1015704]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others examining the Monastery: (12)
As of 2014-08-20 15:53 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The best computer themed movie is:











    Results (118 votes), past polls