unixhome has asked for the wisdom of the Perl Monks concerning the following question:

Hello Monks: I am trying to compare the data in one byte by shifting (>>) and comparing the first bit. I was told that this statement should work:
$a = "data in particular byte" $b = "positions to shift" ((($a >> $b) && ) == 1 );
The statement (when constructed correctly) should return 0 or 1. I would appreciate some pointers on how to accomplish the task. Thanks in advance, RV

Replies are listed 'Best First'.
Re: Help comparing data in byte by shifting (>>) bits
by japhy (Canon) on Jun 15, 2006 at 17:11 UTC
    I think you want if (($a >> $b) & 1) { ... }. That checks to see if the $b'th bit (from the right) is on.

    Jeff japhy Pinyan, P.L., P.M., P.O.D, X.S.: Perl, regex, and perl hacker
    How can we ever be the sold short or the cheated, we who for every service have long ago been overpaid? ~~ Meister Eckhart
Re: Help comparing data in byte by shifting (>>) bits
by samtregar (Abbot) on Jun 15, 2006 at 17:01 UTC
    Whoever told you that would work is misinformed. && is a binary opertor - it requires operands on both sides. Sticking it on the right side of a >> isn't going to get you anywhere.

    Can you explain what you really want to do? Comparing the data in "one byte" is usally done just by comparing characters (since, aside from utf8, characters in Perl are one byte long). If you want extract a single bit from a byte you'll usually use & (not &&) and a bitmask (eg. 0b00000001 to get the first bit).

    -sam

Re: Help comparing data in byte by shifting (>>) bits
by unixhome (Novice) on Jun 15, 2006 at 19:39 UTC
    Guys: Sorry about that. I missed when he said "something like that", which means not exactly it. I am supposed to make it work... Ok so, it is now working. Here is what I have (not exactly...). ;-)
    sub isbitset { my $bytetocheck = $_[0]; my $bittocheck = $_[1]; if (($bytetocheck >> $bittocheck) & 1) { return 1; } else { return 0; } } # End of isbitset function. ################################################## # I am testing all 8 bits to see which one is set. ################################################## printf ("\tByte %08b bit 0 => %d\n\n", ord $uh[0], &isbitset((ord $uh[0]), 0)); printf ("\tByte %08b bit 1 => %d\n\n", ord $uh[0], &isbitset((ord $uh[0]), 1)); printf ("\tByte %08b bit 2 => %d\n\n", ord $uh[0], &isbitset((ord $uh[0]), 2)); printf ("\tByte %08b bit 3 => %d\n\n", ord $uh[0], &isbitset((ord $uh[0]), 3)); printf ("\tByte %08b bit 4 => %d\n\n", ord $uh[0], &isbitset((ord $uh[0]), 4)); printf ("\tByte %08b bit 5 => %d\n\n", ord $uh[0], &isbitset((ord $uh[0]), 5)); printf ("\tByte %08b bit 6 => %d\n\n", ord $uh[0], &isbitset((ord $uh[0]), 6)); printf ("\tByte %08b bit 7 => %d\n\n", ord $uh[0], &isbitset((ord $uh[0]), 7));
    Is it looking any better? Thanks, RV

      FYI, the following all accomplish the same:
      if (($bytetocheck >> $bittocheck) & 1)
      if ($bytetocheck & (1 << $bittocheck))
      if ($bytetocheck & $bit[$bittocheck])
      if (vec($bytetocheck, $bittocheck, 1))

      And in the interest of eliminating redundancy,

      if (($bytetocheck >> $bittocheck) & 1) { return 1; } else { return 0; }

      simplifies to any of the following:
      return (($bytetocheck >> $bittocheck) & 1);
      return ($bytetocheck & (1 << $bittocheck)) ? 1 : 0;
      return ($bytetocheck & $bit[$bittocheck]) ? 1 : 0;
      return vec($bytetocheck, $bittocheck, 1);

      and the following, if you're only interested in returning a boolean value:
      return ($bytetocheck & (1 << $bittocheck));
      return ($bytetocheck & $bit[$bittocheck]);

      You could simply return the value of ($bytetocheck >> $bittocheck) & 1, since it will return 0 or 1. And it's unnecessary to use the '&' when calling your function.

      Jeff japhy Pinyan, P.L., P.M., P.O.D, X.S.: Perl, regex, and perl hacker
      How can we ever be the sold short or the cheated, we who for every service have long ago been overpaid? ~~ Meister Eckhart
        Jeff: Done! Thanks, RV
      Oh yeah, other than:
      for ($tmp = 0 ; $tmp < 8 ; $tmp++) { printf ("\tByte %08b bit $tmp => %d\n\n", ord $uh[0], &isbitset((ord $uh[0]), $tmp)); }