Thread: logical shift and arithmetic shift.(bit shifting in C )

  1. #1
    Registered User
    Join Date
    Sep 2006
    Location
    Beaverton, Oregon, United States
    Posts
    176

    logical shift and arithmetic shift.(bit shifting in C )

    From what I'm told, right shifting of signed integers on some machine cause 1's to be shifted in and on others 0's are shifted in. Now for a signed integer, say -32, is only the last one shifted in as a 1 if its multiple shifts to the right?

    And if its shifting in zeros, how does it know its negative without the 1 in the most significant bit spot? Can someone give me an example of this?
    Last edited by A34Chris; 08-26-2012 at 04:10 AM.

  2. #2
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    Machines that do sign extension just shift in whatever the sign bit is for each shift to the right. This way the sign doesn't change when shifting right.
    Kurt

  3. #3
    Registered User
    Join Date
    Sep 2006
    Location
    Beaverton, Oregon, United States
    Posts
    176
    Quote Originally Posted by ZuK View Post
    Machines that do sign extension just shift in whatever the sign bit is for each shift to the right. This way the sign doesn't change when shifting right.
    Kurt
    So if its 3 shifts to the right it shifts in 3 1s? Beyond the sign bit that would change the value of the number wouldnt it? And what about the ones that shift in zeros?

  4. #4
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    Quote Originally Posted by A34Chris View Post
    So if its 3 shifts to the right it shifts in 3 1s?
    Yes.
    And what about the ones that shift in zeros?
    Don't know. Never worked with such a machine.
    I understand that in C right shifting of signed types is implementation defined. Sign extension might as well be done by code.
    Check the compiler doc.
    Kurt

  5. #5
    Registered User
    Join Date
    May 2012
    Posts
    1,066
    Quote Originally Posted by A34Chris View Post
    Beyond the sign bit that would change the value of the number wouldnt it?
    Right shifting always changes the value of the number, so why should there be a problem?

    Bye, Andreas

  6. #6
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Just do not use the shifting of signed values and you will have no need to understand the undefined behavior caused by it.
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  7. #7
    Registered User
    Join Date
    Sep 2006
    Location
    Beaverton, Oregon, United States
    Posts
    176
    Quote Originally Posted by AndiPersti View Post
    Right shifting always changes the value of the number, so why should there be a problem?

    Bye, Andreas
    Yes its dropping it down by a factor of two but what about the on bits that are shifted in? I'm confused. I'm not sure I'm expressing myself well.

  8. #8
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    Quote Originally Posted by vart View Post
    Just do not use the shifting of signed values and you will have no need to understand the undefined behavior caused by it.
    Actually isn't this implementation defined behavior, not undefined behavior?

    what about the on bits that are shifted in?
    The bits shifted in are 0's.

    Jim
    Last edited by jimblumberg; 08-26-2012 at 10:31 AM.

  9. #9
    Registered User
    Join Date
    Sep 2006
    Location
    Beaverton, Oregon, United States
    Posts
    176
    ok. My assignment is:

    Write a program that determines whether your particular computer performs an arithmetic or logical right shift.
    So I gotta dig a little bit into this topic to wrap my head around it. It is interesting.

  10. #10
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    Quote Originally Posted by A34Chris View Post
    Yes its dropping it down by a factor of two but what about the on bits that are shifted in? I'm confused.
    Just try this
    Code:
    #include <stdio.h>
    
    void print_bits(int value ) {
       unsigned int mask = 1 << 31;
       int i;
       printf("\n%12d = ", value );
       for( i = 31; i >= 0; --i ) {
          printf("%c", value & mask ? '1' : '0' );
          mask >>= 1;
       }
    }
    
    int main() {
        int v = 123;
        print_bits( v );
        print_bits( v >> 2);
        puts("");
        v = -123;
        print_bits( v );
        print_bits( v >> 2);
        puts("");
        return 0;
    }
    my output
    Code:
             123 = 00000000000000000000000001111011
              30 = 00000000000000000000000000011110
    
            -123 = 11111111111111111111111110000101
             -31 = 11111111111111111111111111100001
    The only thing that might be a little confusing is that shifting -123 two positions to the right gives -31. But that is how integer truncation is defined. it gives the next lower value.

    Kurt
    Last edited by ZuK; 08-26-2012 at 11:13 AM.

  11. #11
    Registered User
    Join Date
    Sep 2006
    Location
    Beaverton, Oregon, United States
    Posts
    176
    Thank you! Thats interesting.

    Did you whip that up just now?

  12. #12
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    Quote Originally Posted by jimblumberg View Post
    Actually isn't this implementation defined behavior, not undefined behavior?
    The bits shifted in are 0's.
    You're contradicting yourself! It is, as you say, implementation defined, so it's not always 0's.

    The bits shifted in are 0's if the sign bit is 0 no matter what the implementation's choice between arithmetic or logical shifts.

    But if the number is negative, then an arithmetic shift will shift in 1's while a logical shift will still shift in 0's. Thus, an arithmetic shift retains the sign of the number.

    So to tell which one your machine uses (my guess is arithmetic!), just take a negative number, shift it one place right, and see if it's still negative.
    Code:
    int n = -1;
    n >>= 1;
    puts((n < 0) ? "arithmetic" : "logical");
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  13. #13
    Registered User
    Join Date
    Sep 2006
    Location
    Beaverton, Oregon, United States
    Posts
    176
    God I wish I had a printer.

  14. #14
    Registered User
    Join Date
    Sep 2006
    Location
    Beaverton, Oregon, United States
    Posts
    176
    I also have a system with a motorola 68000. I can run this code on that too and see if it does a logical or arithmetic right shift. Very interesting!

    Thank you all for your time and help! This has been very informative. Dont lock this thread, I might be back next week with more questions!

  15. #15
    Registered User
    Join Date
    May 2012
    Posts
    1,066
    And if you want to simulate a logical shift on an implementation which uses arithmetic shift add the following line to Kurt's code:
    Code:
    print_bits((v >> 2) & 0x3FFFFFFF);   // assuming your ints are 4 bytes
    Bye, Andreas

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Logical Right Shift
    By theotherindian in forum C Programming
    Replies: 10
    Last Post: 09-22-2011, 01:26 PM
  2. Bit shift
    By nenpa8lo in forum C Programming
    Replies: 8
    Last Post: 09-03-2008, 07:30 AM
  3. arithmatic vs logical shift operation
    By onebrother in forum C Programming
    Replies: 2
    Last Post: 02-21-2008, 04:21 AM
  4. Shift operators in C
    By jedi_jinn in forum C Programming
    Replies: 4
    Last Post: 10-23-2006, 02:52 AM
  5. Shift Key
    By gnu-ehacks in forum A Brief History of Cprogramming.com
    Replies: 14
    Last Post: 01-31-2002, 05:47 PM