Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ Breaking DWORD into characters

I have a four byte DWORD that I need to split into four different characters. I thought I knew how to accomplish this but am getting bizarre numbers every time. Here is my code:

    // The color memory
    int32 col = color_mem[i];

    // The four destination characters
    char r, g, b, a;

    // Copy them in advancing by one byte every time
    memcpy(&r, &col, 1);
    memcpy(&g, &col + 1, 1);
    memcpy(&b, &col + 2, 1);
    memcpy(&a, &col + 3, 1);
like image 208
Pladnius Brooks Avatar asked Dec 01 '25 05:12

Pladnius Brooks


2 Answers

Ditch the memcpy and use bit manipulation:

r = (col & 0x000000ff);
g = (col & 0x0000ff00) >>  8;
b = (col & 0x00ff0000) >> 16;
a = (col & 0xff000000) >> 24;

ff in the hexadecimal numbers represents a byte of all 1 bits. This and the & - bitwise AND - will make the bytes that you're not interested in - at each position - 0, and keeping the bits that you are interested in.

The >> shifts in zeros from the left, putting the byte that we want in the most significant position, for the actual assignment. A shift of 8 shifts by a width of one byte, 16 is two bytes, and 24 is three bytes.

Visually, looking at ff, you can imagine that we're walking the byte indices towards the left.

like image 165
pb2q Avatar answered Dec 02 '25 18:12

pb2q


When you do pointer arithmetic, the amount of the increment or decrement is multiplied by the size of the type being pointed to. Cast the int32 pointer to a char pointer in order to access char sized parts at some offset from the base address of col.

This technique can be fragile due to differences in endian-ness on different platforms, so I recommend using the more portable bitmask operations supplied in another answer.

// The color memory  
int32 col = color_mem[i];  

// The four destination characters  
char r, g, b, a;  

// Copy them in advancing by one byte every time  
memcpy(&r, (char*)&col, 1);  
memcpy(&g, ((char*)&col) + 1, 1);  
memcpy(&b, ((char*)&col) + 2, 1);  
memcpy(&a, ((char*)&col) + 3, 1); 
like image 22
Monroe Thomas Avatar answered Dec 02 '25 19:12

Monroe Thomas



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!