How to Convert Between Big-Endian and Little-Endian Values in C++

How do I convert between big-endian and little-endian values in C++?

If you're using Visual C++ do the following: You include intrin.h and call the following functions:

For 16 bit numbers:

unsigned short _byteswap_ushort(unsigned short value);

For 32 bit numbers:

unsigned long _byteswap_ulong(unsigned long value);

For 64 bit numbers:

unsigned __int64 _byteswap_uint64(unsigned __int64 value);

8 bit numbers (chars) don't need to be converted.

Also these are only defined for unsigned values they work for signed integers as well.

For floats and doubles it's more difficult as with plain integers as these may or not may be in the host machines byte-order. You can get little-endian floats on big-endian machines and vice versa.

Other compilers have similar intrinsics as well.

In GCC for example you can directly call some builtins as documented here:

uint32_t __builtin_bswap32 (uint32_t x)
uint64_t __builtin_bswap64 (uint64_t x)

(no need to include something). Afaik bits.h declares the same function in a non gcc-centric way as well.

16 bit swap it's just a bit-rotate.

Calling the intrinsics instead of rolling your own gives you the best performance and code density btw..

Conversion to little endian format in C [duplicate]

#define BS16(x) (((x) >> 8) | ((x) << 8))
int main(void)
{
uint16_t arr[] = {0x1122, 0x2233, 0xaabb};
printf("%hx %hx %hx\n", BS16(arr[0]), BS16(arr[1]), BS16(arr[2]));
arr[0] = BS16(arr[0]);
}

Convert Little Endian to Big Endian

OP's sample code is incorrect.

Endian conversion works at the bit and 8-bit byte level. Most endian issues deal with the byte level. OP code is doing a endian change at the 4-bit nibble level. Recommend instead:

// Swap endian (big to little) or (little to big)
uint32_t num = 9;
uint32_t b0,b1,b2,b3;
uint32_t res;

b0 = (num & 0x000000ff) << 24u;
b1 = (num & 0x0000ff00) << 8u;
b2 = (num & 0x00ff0000) >> 8u;
b3 = (num & 0xff000000) >> 24u;

res = b0 | b1 | b2 | b3;

printf("%" PRIX32 "\n", res);

If performance is truly important, the particular processor would need to be known. Otherwise, leave it to the compiler.

[Edit] OP added a comment that changes things.

"32bit numerical value represented by the hexadecimal representation (st uv wx yz) shall be recorded in a four-byte field as (st uv wx yz)."

It appears in this case, the endian of the 32-bit number is unknown and the result needs to be store in memory in little endian order.

uint32_t num = 9;
uint8_t b[4];
b[0] = (uint8_t) (num >> 0u);
b[1] = (uint8_t) (num >> 8u);
b[2] = (uint8_t) (num >> 16u);
b[3] = (uint8_t) (num >> 24u);

[2016 Edit] Simplification

... The type of the result is that of the promoted left operand.... Bitwise shift operators C11 §6.5.7 3

Using a u after the shift constants (right operands) results in the same as without it.

b3 = (num & 0xff000000) >> 24u;
b[3] = (uint8_t) (num >> 24u);
// same as
b3 = (num & 0xff000000) >> 24;
b[3] = (uint8_t) (num >> 24);

Convert Little Endian to Big Endian - Not getting expected result

If you do 0x8000 << 8 you'll get 0x800000. If you | that with 0x80 you get the answer you now get. You need to filter away the upper part:

int swap = (num>>8) | (0xFF00 & (num<<8));

Suggestion: Use fixed width types, like uint8_t, uint16_t, uint32_t and uint64_t.

Convert array of Ints into array of Little-Endian Bytes in C#

One thing you could do is use the EndianBitConverter project from Nuget. It does what it says on the tin and provides a way of converting to either big-endian or little-endian.

Once you have got it installed, you can write code like this:

var intList = new List<int> { 91233, 67278, 22345, 45454, 23449 };

foreach ( var n in intList)
{
var result1 = EndianBitConverter.LittleEndian.GetBytes(n);
var result2 = EndianBitConverter.BigEndian.GetBytes(n);
}

If you want to do it as a 1 liner, then perhaps something like this:

var intList = new List<int> { 91233, 67278, 22345, 45454, 23449 };
var result = intList.Select(x => EndianBitConverter.LittleEndian.GetBytes(x)).ToList();

Converting any variable from big to little endian - how to avoid void pointers?

One problem you have is that you're leaking memory. You return a pointer to malloc'ed memory, but you're not saving the pointer when you return.

Given that you're assigning the result back to the same value, you're better off updating the existing variable, swapping the current byte with a byte on the "opposite" side.

You also don't need to use a void * anyplace other than the parameter type. Inside of the function, just use a pointer to an unsigned char or unsigned __int8 to work through the bytes.

void swapBytes(void* number, int bytes_num)
{
unsigned __int8* ptr = number;
for (int i = 0; i<bytes_num/2; i++) {
unsigned __int8 tmp = ptr[i];
ptr[i] = ptr[bytes_num-1-i];
ptr[bytes_num-1-i] = tmp;
}
}

Then call it like this:

swapBytes(&big_number, sizeof(big_number));


Related Topics



Leave a reply



Submit