Question

I need to swap every two adjacent bits as a generic operation which will do so for every variable type given.

I thought of the needed masks and operations for every single byte:

(var & 0x55) << 1 | (var & 0xAA) >> 1

But how do I make this apply for let's say an integer? Do I need to create an array of sizeof(int) unsigned chars with the above masks and apply the operation that way?

Was it helpful?

Solution

You can do this byte by byte (the same as char by char).

For example:

int n = 0xAA55A55A;
unsigned char *p = (unsigned char *) &n;

for (; p < (unsigned char *) &n + sizeof(n); p++)
   *p = (*p & 0x55) << 1 | (*p & 0xAA) >> 1;

OTHER TIPS

Two suggestions: Instead of using the logic operations, you can use a look up table of 256 chars.:

char lookUpTable[256] = {0x00, 0x02, 0x01 ...};

If you dont want to initialize this lookup statically, you can write a function that initialize it using logic operations.

When you want to swap byte b, you either simply write lookUpTable[b], or you wrap this with a function.

As for swapping any type, you write a function that does something like:

void SwapBits(char* data, size_t len)
{
    For (; len > 0; len--)
    {
        *data = lookUpTable[*data];
        data++;
    }
}

You then use this like this:

AnyType swapMe = whatever;
SwapBits((char*)(&swapMe), sizeof(AnyType));

Note this replaces the "contents" of swapMe.

One more thing, the right shift behavior is architecrure specific, some architectures may sign extend on right shift. It would be more generic to use an expression like:

SwappedByte = ((Byte >> 1)&0x55) | ((Byte << 1)&0xaa)

As this way you remove any sign extension artifacts.

Something like this. Cast the address of any variable to a char * and you can iterate over the bytes.

#include <stdio.h>

char swap_c(char);
void swap_r(char *, int);

int main(void) {
    char c = 10;
    c = swap_c(c);
    printf("%i\n", c);
    int i = 10;
    char * r = (char *) &i; //you can cast the address of any variable into a char *
    swap_r(r, sizeof(int));
    printf("%i\n", i);
}

void swap_r(char * c, int length) {
    int i = 0;
    while(i < length) {
        c[i] = swap_c(c[i]);
        i++;
    }       
}

char swap_c(char c) {
    return (c & 0x55) << 1 | (c & 0xAA) >> 1;
}

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