19

This question is basically the second half to my other Question

How can I convert a UINT16 value, into a UINT8 * array without a loop and avoiding endian problems.

Basically I want to do something like this:

UINT16 value = 0xAAFF;
UINT8 array[2] = value;

The end result of this is to store value into a UINT8 array while avoiding endian conversion.

UINT8 * mArray;
memcpy(&mArray[someOffset],&array,2);

When I simply do memcpy with the UINT16 value, it converts to little-endian which ruins the output. I am trying to avoid using endian conversion functions, but think I may just be out of luck.

Community
  • 1
  • 1
dp.
  • 229
  • 1
  • 2
  • 11

6 Answers6

47

How about

UINT16 value = 0xAAFF;
UINT8 array[2];
array[0]=value & 0xff;
array[1]=(value >> 8);

This should deliver the same result independent of endianness.

Or, if you want to use an array initializer:

UINT8 array[2]={ value & 0xff, value >> 8 };

(However, this is only possible if value is a constant.)

Martin B
  • 23,670
  • 6
  • 53
  • 72
8

There's no need for conditional compilation. You can bit-shift to get the higher and lower byte of the value:

uint16_t value = 0xAAFF;
uint8_t hi_lo[] = { (uint8_t)(value >> 8), (uint8_t)value }; // { 0xAA, 0xFF }
uint8_t lo_hi[] = { (uint8_t)value, (uint8_t)(value >> 8) }; // { 0xFF, 0xAA }

The casts are optional.

Christoph
  • 164,997
  • 36
  • 182
  • 240
6

Assuming that you want to have the high-order byte above the lower-order byte in the array:

array[0] = value & 0xff;
array[1] = (value >> 8) & 0xff;
Jonathan
  • 13,354
  • 4
  • 36
  • 32
  • 3
    the mask `0xff` is unnecessary: the conversion from 16 to 8 bit integers will drop the higher byte (unsigned conversion is well-defined!) – Christoph Aug 17 '09 at 17:47
  • 4
    That's true, but I generally mask everything for clarity. Sometimes, I'll even do a bit-shift by 0 so that the lines all match up and look good vertically. Any good compiler will optimize out the unnecessary statements, and it is well worth the clarity. – Jonathan Aug 18 '09 at 13:31
1
union TwoBytes
{
    UINT16 u16;
    UINT8 u8[2];
};

TwoBytes Converter;
Converter.u16 = 65535;
UINT8 *array = Converter.u8;
Niki Yoshiuchi
  • 16,883
  • 1
  • 35
  • 44
0

A temporary cast to UINT16* should do it:

((UINT16*)array)[0] = value;
RightFullRudder
  • 562
  • 4
  • 12
  • 1
    This doesn't work because it's still sensitive to endianness (basically, it does the same thing as the `memcpy` in the question). – Martin B Aug 17 '09 at 17:40
0

I used this thread to develop a solution that spans arrays of many sizes:

UINT32 value = 0xAAFF1188;
int size = 4;
UINT8 array[size];

int i;
for (i = 0; i < size; i++)
{
    array[i] = (value >> (8 * i)) & 0xff;
}
omikes
  • 8,064
  • 8
  • 37
  • 50