Jump to content
  • Advertisement
Sign in to follow this  
TEUTON

Big Endian and Little Endian

This topic is 4480 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I was trying to swap big-endian and little endian... and wrote this code...I guess this is sufficient...but this is for unsigned types...can you suggest some code for signed types??
inline void endian_swap(unsigned short& x)
{
    x = (x>>8) | (x<<8);
}

Share this post


Link to post
Share on other sites
Advertisement
Guest Anonymous Poster
Not entirely positive, but assuming 2's complement, signedness shouldn't make a difference.

Share this post


Link to post
Share on other sites
For little endian anyway, where the first bytes in memory are lower significance, the last byte has the sign bit (for each integer data type and IEEE float type this is true, anyway).

I'm guessing that in big endian, the sign bit is still in the "most significant byte" (which is the first on in that case).

It's probably possible to think of endianness as being "lower level" than signedness.


As for code, you can probably do some clever typecasting to force the compiler to switch signedness. Also, if you're ever manually converting a signed value from a smaller to larger value, you might have to sign-extend it.

(Sign extension means that if the sign bit is 1, fill the 'new' bytes in the larger type with 1s to keep the same value)

Share this post


Link to post
Share on other sites
Quote:
Original post by Anonymous Poster
Not entirely positive, but assuming 2's complement, signedness shouldn't make a difference.


In 2's complement signednes makes a big difference. The OP's code will not work properly with a signed numeric type. The right shift will fill the upper byte with all 1's which will result in incorrect values whenever the lower byte isn't 0xFF. To do an endian swap with a signed type just cast it to unsigned, swap it, and cast it back. The casting can be handled implicitly, but some compilers will spit out warnings if you don't explicitly cast.

Share this post


Link to post
Share on other sites
Quote:
Original post by Troll
The right shift will fill the upper byte with all 1's....


It varies from machine to machine.

Share this post


Link to post
Share on other sites
In which case it may be more prudent to do something like this:


inline void endian_swap(unsigned short& x)
{
char * k = reinterpret_cast<char*>(&x);
std::swap(k[0], k[1]);
}



Untested, seems right.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Quote:
Original post by Troll
Quote:
Original post by Anonymous Poster
Not entirely positive, but assuming 2's complement, signedness shouldn't make a difference.


In 2's complement signednes makes a big difference. The OP's code will not work properly with a signed numeric type. The right shift will fill the upper byte with all 1's which will result in incorrect values whenever the lower byte isn't 0xFF. To do an endian swap with a signed type just cast it to unsigned, swap it, and cast it back. The casting can be handled implicitly, but some compilers will spit out warnings if you don't explicitly cast.


Does the right shift treat signed and unsigned differently? I thought it'd treat them the same, especially because they look exactly the same under 2's complement (i.e. there is a bijection between unsigned int's greater than INT_MAX and signed int's less than 0), which is why we use 2's complement in the first place.

Share this post


Link to post
Share on other sites
Quote:
Original post by _goat
In which case it may be more prudent to do something like this:

*** Source Snippet Removed ***

Untested, seems right.


But..you haven't casted it to unsigned type...or have you??

Share this post


Link to post
Share on other sites
I know from experience that different compilers, platforms, etc. will behave differently with right shifts on signed integers. Some will sign extend, some will shift in zeroes. The standard says the behavior is implementation defined. In other words, don't rely on it.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!