Question

I need to make an assignment where I switch the values of a certain int. For example: 0xaabbccdd should be turned in to 0xddccbbaa.

I've already extraced all of the bytes from the given number and their values are correct.

unsigned int input;

scanf("%i", &input);

unsigned int first_byte = (input >> (8*0)) & 0xff;
unsigned int second_byte = (input >> (8*1)) & 0xff;
unsigned int third_byte = (input >> (8*2)) & 0xff;
unsigned int fourth_byte = (input >> (8*3)) & 0xff;

Now I'm trying to set an empty int variable (aka 00000000 00000000 00000000 00000000) to those byte values, but turned around. So how can I say that the first byte of the empty variable is the fourth byte of the given input? I've been trying different combinations of bitwise operations, but I can't seem to wrap my head around it. I'm pretty sure I should be able to do something like:

answer *first byte* | fourth_byte;

I would appreciate any help, becau'se I've been stuck and searching for an answer for a couple of hours now.

Was it helpful?

Solution

Based on your code :

#include <stdio.h>

int main(void)
{
    unsigned int input = 0xaabbccdd;
    unsigned int first_byte = (input >> (8*0)) & 0xff;
    unsigned int second_byte = (input >> (8*1)) & 0xff;
    unsigned int third_byte = (input >> (8*2)) & 0xff;
    unsigned int fourth_byte = (input >> (8*3)) & 0xff;

    printf(" 1st : %x\n 2nd : %x\n 3rd : %x\n 4th : %x\n", 
        first_byte, 
        second_byte, 
        third_byte, 
        fourth_byte);

    unsigned int combo = first_byte<<8 | second_byte;
    combo = combo << 8 | third_byte;
    combo = combo << 8 | fourth_byte;

    printf(" combo : %x ", combo);

    return 0;
}

It will output 0xddccbbaa

Here's a more elegant function to do this :

unsigned int setByte(unsigned int input, unsigned char byte, unsigned int position)
{
    if(position > sizeof(unsigned int) - 1)
        return input;

    unsigned int orbyte = byte;
    input |= byte<<(position * 8);

    return input;
}

Usage :

unsigned int combo = 0;
    combo = setByte(combo, first_byte, 3);
    combo = setByte(combo, second_byte, 2);
    combo = setByte(combo, third_byte, 1);
    combo = setByte(combo, fourth_byte, 0);

    printf(" combo : %x ", combo);

OTHER TIPS

unsigned int result;

result = ((first_byte <<(8*3)) | (second_byte <<(8*2)) | (third_byte <<(8*1)) | (fourth_byte))

You can extract the bytes and put them back in order as you're trying, that's a perfectly valid approach. But here are some other possibilities:

bswap, if you have access to it. It's an x86 instruction that does exactly this. It doesn't get any simpler. Similar instructions may exist on other platforms. Probably not good for a C assignment though.

Or, swapping adjacent "fields". If you have AABBCCDD and first swap adjacent 8-bit groups (get BBAADDCC), and then swap adjacent 16-bit groups, you get DDCCBBAA as desired. This can be implemented, for example: (not tested)

x = ((x & 0x00FF00FF) <<  8) | ((x >>  8) & 0x00FF00FF);
x = ((x & 0x0000FFFF) << 16) | ((x >> 16) & 0x0000FFFF);

Or, a closely related method but with rotates. In AABBCCDD, AA and CC are both rotated to the left by 8 positions, and BB and DD are both rotated right by 8 positions. So you get:

x = rol(x & 0xFF00FF00, 8) | ror(x & 0x00FF00FF, 8);

This requires rotates however, which most high level languages don't provide, and emulating them with two shifts and an OR negates their advantage.

#include <stdio.h>

int main(void)
{
    unsigned int input = 0xaabbccdd,
                 byte[4] = {0},
                 n = 0,
                 output = 0;
    do
    {
        byte[n] = (input >> (8*n)) & 0xff;
        n = n + 1;
    }while(n < 4);

    n = 0;
    do
    {
        printf(" %d : %x\n", byte[n]);
        n = n + 1;
    }while (n < 4);

    n = 0;
    do
    {
        output = output << 8 | byte[n];
        n = n + 1;
    }while (n < 4);

    printf(" output : %x ", output );

    return 0;
}

You should try to avoid repeating code.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top