#1
  1. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2011
    Posts
    61
    Rep Power
    7

    Bitmasking Question


    How do I test to see if a bit is set and get the corresponding variable from a hash? for example:

    Code:
    #!/usr/perl5/bin;
    
    my %states = (
    	in 		=> 1 << 7,
    	out 	=> 1 << 6,
    	up 		=> 1 << 5,
    	down	=> 1 << 4,
    	left 	=> 1 << 3,
    	right 	=> 1 << 2,
    	around 	=> 1 << 1,
    	about 	=> 1 << 0,
    	
    );
    
    my $complement = 0xff;
    my $mask = 0x80;
    my $bits = $complement & $mask;
    $bits = sprintf ("%2b", $bits);
    foreach my $key (keys %states){
    	$states{$key} = sprintf ("%2b", $states{$key});
    	print "$states{$key}\n"; #debug print
    	if ($bits |= $states{$key}{
    		print "$key\n";
    	}
    }
    The goal is to be able to take a byte and correlate it to the hash. The above program should print "in" and does if I use == instead of |= but that's no good because it would miss more than one bit being set. What can I change in my if statement to get this to work?
  2. #2
  3. No Profile Picture
    Contributing User
    Devshed Regular (2000 - 2499 posts)

    Join Date
    Apr 2009
    Posts
    2,232
    Rep Power
    1296
    Your code won't compile. Please correct your code so that it will compile and demonstrate the problem.

    Also, make sure your code includes
    Code:
    use warnings;
    use strict;
    Last edited by FishMonger; June 5th, 2017 at 07:51 PM.
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2011
    Posts
    61
    Rep Power
    7
    Originally Posted by FishMonger
    Your code won't compile. Please correct your code so that it will compile and demonstrate the problem.
    Code:
    #!/usr/perl5/bin;
    
    my %states = (
    	in 		=> "1 << 7",
    	out 	=> "1 << 6",
    	up 		=> "1 << 5",
    	down	=> "1 << 4",
    	left 	=> "1 << 3",
    	right 	=> "1 << 2",
    	around 	=> "1 << 1",
    	about 	=> "1 << 0",
    	
    );
    
    my $complement = 0xff;
    my $mask = 0x80;
    my $bits = $complement & $mask;
    $bits = sprintf ("%2b", $bits);
    print "\n\n$bits\n\n";
    foreach my $key (keys %states){
    	$states{$key} = sprintf ("%8b", $states{$key});
    	print "$states{$key}\n"; #debug print
    	if ($bits |= $states{$key}) {
    		print "$key\n";
    	}
    }
    I just ran this with some extra printing for debug.
  6. #4
  7. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2011
    Posts
    61
    Rep Power
    7
    Sorry, that one is wrong. I don't need quotes in my hash. This one is better. The if statement always prints all of the keys:

    Code:
    #!/usr/perl5/bin;
    
    my %states = (
    	in 		=> 1 << 7,
    	out 	=> 1 << 6,
    	up 		=> 1 << 5,
    	down	=> 1 << 4,
    	left 	=> 1 << 3,
    	right 	=> 1 << 2,
    	around 	=> 1 << 1,
    	about 	=> 1 << 0,
    	
    );
    
    my $complement = 0xFF;
    my $mask = 0x80;
    my $bits = $complement & $mask;
    $bits = sprintf ("%2b", $bits);
    print "\n\n$bits\n\n";
    foreach my $key (keys %states){
    	$states{$key} = sprintf ("%2b", $states{$key});
    	print "$states{$key}\n"; #debug print
    	if ($bits |= $states{$key}) {
    		print "$key\n";
    	}
    }
  8. #5
  9. No Profile Picture
    Contributing User
    Devshed Regular (2000 - 2499 posts)

    Join Date
    Apr 2009
    Posts
    2,232
    Rep Power
    1296
    By not including the warnings and strict pragmas, you're telling perl not to inform you of your problems.

    Code:
    C:\test>dolfantb.pl
    
    
    10000000
    
    Argument "1 << 7" isn't numeric in sprintf at C:\test\dolfantb.pl line 24.
           1
    in
    Argument "1 << 0" isn't numeric in sprintf at C:\test\dolfantb.pl line 24.
           1
    about
    Argument "1 << 4" isn't numeric in sprintf at C:\test\dolfantb.pl line 24.
           1
    down
    Argument "1 << 3" isn't numeric in sprintf at C:\test\dolfantb.pl line 24.
           1
    left
    Argument "1 << 6" isn't numeric in sprintf at C:\test\dolfantb.pl line 24.
           1
    out
    Argument "1 << 2" isn't numeric in sprintf at C:\test\dolfantb.pl line 24.
           1
    right
    Argument "1 << 5" isn't numeric in sprintf at C:\test\dolfantb.pl line 24.
           1
    up
    Argument "1 << 1" isn't numeric in sprintf at C:\test\dolfantb.pl line 24.
           1
    around
  10. #6
  11. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2011
    Posts
    61
    Rep Power
    7
    Got it, I had some unnecessary binary conversions:

    Code:
    #!/usr/perl5/bin;
    use warnings;
    
    
    my %states = (
    	in 		=> 1 << 7,
    	out 	=> 1 << 6,
    	up 		=> 1 << 5,
    	down	=> 1 << 4,
    	left 	=> 1 << 3, 
    	right 	=> 1 << 2,
    	around 	=> 1 << 1,
    	about 	=> 1 << 0,
    	
    );
    
    my $complement = 0x0f;
    print "\n\n$complement\n\n";
    foreach my $key (keys %states){
    	if ( $complement & $states{$key}) {
    		print "$key\n";
    	}
    }

IMN logo majestic logo threadwatch logo seochat tools logo