in reply to Shift Operators And Bitwise Operators

# bitfield format: xxxMMMxx my @msgs = ( 'a' .. 'i' ); my $msg = $msgs[ ( $bitfield >> 2 ) && 7 ];

It's also used in doing checksums, hashing, encryption, doing exponent changes in fixed-point arithmetic, quick multiplications and divisions by powers of two, etc, etc.

Update: I missed that you also asked about bitwise operators. They are usually used to extract informations from numbers that contains multiple flags or fields. For example, system returns a number that consists of 3 fields:

bit15 bit0 | | v v C SSSSSSS EEEEEEEE C = Core dumped? S = Signal that caused program to exit E = Process's exit code.

These can be extracted as follows:

$core_dumped = ($? >> 15) & 1; $signal = ($? >> 8) & 127; $exit_code = $? & 255

Replies are listed 'Best First'.
Re^2: Shift Operators And Bitwise Operators
by biohisham (Priest) on Jun 22, 2009 at 18:31 UTC
    hahaha, I have really been stuck...u said the shift operators can be used in Checksums, hashing, encryption...is there anywhere I can actually get to see such examples? I want to learn more, I feel it is important to master these. In the second example, you shifted 15 bits to the right of the value of $? and 8 and bits as well, but you have &ed that while for the last $? of $exit_code, you only &ed...what does & do in this context..only in this context...

      In a 32-bit int,

      $core_dumped = ($? >> 15) & 1; 00000000 00000000 CSSSSSSS EEEEEEEE >> 15 00000000 00000000 00000000 0000000C & 1 00000000 00000000 00000000 00000001 = 1 00000000 00000000 00000000 0000000C

      Ok, everything to the left of "C" should always be zero, so the & 1 doesn't do anything. Me bad. The signal one is a better example:

      $signal = ($? >> 8) & 127; 00000000 00000000 CSSSSSSS EEEEEEEE >> 8 00000000 00000000 00000000 CSSSSSSS & 127 00000000 00000000 00000000 01111111 = 127 00000000 00000000 00000000 0SSSSSSS

      The shift repositioned the bits of interest and removed the lower-precision bits we didn't want.

      The "and" removed the higher-precision bits we didn't want.

      You could do the operations in the opposite order:

      $signal = ($? & 0x7F00) >> 8; 00000000 00000000 CSSSSSSS EEEEEEEE & 0x00007F00 00000000 00000000 01111111 00000000 = 0x00007F00 00000000 00000000 0SSSSSSS 00000000 >> 8 00000000 00000000 00000000 0SSSSSSS

      The "and" removed all the bits we didn't want.

      The shift repositioned the bits of interest.

      You should be start by understanding how machines store integers.

        Great, I think I am getting it somehow, albeit in a random way... I can summarize this as follows
        #working in octets of bits. 01-shift $! bits to the right. #zeroing on target 02-spread &ing carpet under the target #2**(No.of bits) #carpet size is (1,4,8,16,32) that covers 1,2,3,4..etc bits #from the second bit the relation is (2**2, 2**3, #2**4...2**32) i.e. +2**(bit position). 03-&ing makes us extract the bits we want #(shifted bits)*(appropriate carpet size)=(C or SSs or EEs)
        does this seem all there is to it??? p.s. I don't know anything about carpets by the way except that they are spread or pinned on to a wall

      In the system example, you have a 16 bit integer which holds three values. One value is the 15th bit, one is bits 14-8, and the last is 7-0. In order to extract those values, the common way to do this is to shift over the appropriate number of bits, then mask off the unneeded bits.

      For an example, let's use the field 1100 0001 0000 1111. The first value is a 1, the second is 100 0001, and the third is 0000 1111.

      To get the first value, shift to the right 15 bits, then AND that with 1. What's really happening is you are ANDing it with a bunch of leading zeros, and then a final one. So in this case, ANDing a one with a one yields one.

      It's more interesting (and it makes the reason for the ANDing more apparent) when getting the second value. You right shift 8 bits, ending up with (with leading zeros) 0000 0000 1100 0001. If you were to then get this value, you would end up with 193. The problem here is that we only want the first 7 bits, but we've got that 8th bit in there. So we zero out the high bits by ANDing it with 0111 1111. This results in 0100 0001, or 65.