Thread: Bit shifting and Endianness

  1. #1
    Registered User
    Join Date
    May 2009
    Posts
    242

    Bit shifting and Endianness

    If one writes in C or C++
    Code:
    int x = 1 << 2;
    Is it guaranteed regardless of platform that x is now 4? I was thinking it would have to be, but a friend was claiming that on some platforms the value may be different.

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Aisthesis
    Is it guaranteed regardless of platform that x is now 4?
    Yes. Here's the relevant text from the next most recent version of the C standard, where ** denotes exponentiation:
    Quote Originally Posted by C99 Clause 6.5.7 Paragraph 4
    The result of E1 << E2 is E1 left-shifted E2 bit positions; vacated bits are filled with zeros. If E1 has an unsigned type, the value of the result is E1 * 2**E2, reduced modulo one more than the maximum value representable in the result type. If E1 has a signed type and nonnegative value, and E1 * 2**E2 is representable in the result type, then that is the resulting value; otherwise, the behavior is undefined.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    The answer lies in the C standard:
    Quote Originally Posted by C99 6.5.7
    4 The result of E1 << E2 is E1 left-shifted E2 bit positions; vacated bits are filled with
    zeros. If E1 has an unsigned type, the value of the result is E1 × 2^E2, reduced modulo
    one more than the maximum value representable in the result type. If E1 has a signed
    type and nonnegative value, and E1 × 2^E2 is representable in the result type, then that is
    the resulting value; otherwise, the behavior is undefined.
    5 The result of E1 >> E2 is E1 right-shifted E2 bit positions. If E1 has an unsigned type
    or if E1 has a signed type and a nonnegative value, the value of the result is the integral
    part of the quotient of E1 / 2^E2. If E1 has a signed type and a negative value, the
    resulting value is implementation-defined.
    Basically, in that case, it will always be 4, regardless of platform, since E1 (1 in your expression) is positive, and E1 * 2^E2 fits in an integer. If you used -2 instead of 2, or E1 was really large (like 2,147,483,647), behavior would be undefined, i.e. you can't trust it on any platform. It's the right-shift operator that is has implementation-defined behavior and may vary from platform to platform.

  4. #4
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Quote Originally Posted by Aisthesis View Post
    If one writes in C or C++
    Code:
    int x = 1 << 2;
    Is it guaranteed regardless of platform that x is now 4? I was thinking it would have to be, but a friend was claiming that on some platforms the value may be different.
    Endianness is relevant only when data is moved from a big endian to a little endian system or vice versa, otherwise the result of computations or comparisons aren't altered.

  5. #5
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by itCbitC View Post
    Endianness is relevant only when data is moved from a big endian to a little endian system or vice versa, otherwise the result of computations or comparisons aren't altered.
    No, it's also relevant when you have code that treats data as types of different sizes. I.e. treating the memory where ints are stored as memory where just chars are stored.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  6. #6
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Quote Originally Posted by iMalc View Post
    No, it's also relevant when you have code that treats data as types of different sizes.
    Hmm! so what's your point, because that'd be every piece of high level language code
    Quote Originally Posted by iMalc View Post
    I.e. treating the memory where ints are stored as memory where just chars are stored.
    Not sure what you are trying to get at here? How is that going to upset calculations or computations that will be performed? Unless you provide more details I'm unable to see the light of your argument.

  7. #7
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Reading it again I still think it's perfectly clear. Perhaps you understand code better:
    Code:
    int x = 0x12345678;
    char *y = (char*)&x;
    printf("%c", y[1]);
    If you could point out the spot where the data was moved between systems with different endianness in the above code, I'd be happy to take my comment back.

    If on the other hand you can see now how the above code will simply give different results for the different systems it may be run on then perhaps you understand my comment now.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  8. #8
    Registered User
    Join Date
    May 2012
    Location
    Arizona, USA
    Posts
    948
    Quote Originally Posted by iMalc View Post
    Reading it again I still think it's perfectly clear. Perhaps you understand code better:
    Code:
    int x = 0x12345678;
    char *y = (char*)&x;
    printf("%c", y[1]);
    Nitpick: on systems where sizeof(int) == 1, y[1] is undefined. Something like y[sizeof(int)-1] should work on all systems, though.

    Now back to the real world where sizeof(int) >= 2 on most systems anyway....

  9. #9
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Quote Originally Posted by iMalc View Post
    Reading it again I still think it's perfectly clear. Perhaps you understand code better:
    Code:
    int x = 0x12345678;
    char *y = (char*)&x;
    printf("%c", y[1]);
    If you could point out the spot where the data was moved between systems with different endianness in the above code, I'd be happy to take my comment back.
    In that case you missed the point I was making in my post i.e. endianness doesn't affect computations or comparisons done on disparate systems.
    Code:
    int i, j, k;
    k = i * j;
    Will give the same output irrespective of endianness, otherwise what's the point.
    Quote Originally Posted by iMalc View Post
    If on the other hand you can see now how the above code will simply give different results for the different systems it may be run on then perhaps you understand my comment now.
    I was referring to the OP's concern on bit shifting an int quantity, whose output doesn't depend on endianness. Of course walking along an int or float with a char* would print the bytes from the left on big endian and from the right on little endian but that is not a computation or a comparison but merely a way of showing how data is stored in memory on systems with different endianness.

    Hope that makes it clear

  10. #10
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Alright, we understand each other. I was clearly a bit nitpicky on your use of the word "only".
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Endianness of machine
    By naspek in forum C Programming
    Replies: 8
    Last Post: 01-18-2011, 10:24 AM
  2. Endianness and bit shifting
    By synthetix in forum C Programming
    Replies: 27
    Last Post: 06-07-2009, 01:06 AM
  3. Changing endianness
    By slippy in forum C++ Programming
    Replies: 9
    Last Post: 03-26-2009, 01:17 PM
  4. endianness and bit shifting
    By Dino in forum Tech Board
    Replies: 7
    Last Post: 01-30-2008, 11:53 PM
  5. endianness
    By DavidP in forum Tech Board
    Replies: 4
    Last Post: 06-13-2004, 04:44 PM