unsigned int swapbits(unsigned int a) { bool bit6 = a & (1 << 5); bool bit17 = a & (1 << 16); if (bit6 == bit17) return a; //bits are the same, do nothing return (a ^ (1 << 5) ^ (1 << 16)); // flip both 6th and 17th bits }
Not as efficient as mine, but kudos.
gcc and clang give
swap: # @swap mov ecx, edi shr ecx, 11 and ecx, 32 mov eax, edi and eax, -65569 or eax, ecx and edi, 32 shl edi, 11 or eax, edi ret swap: mov eax, edi mov edx, edi and edi, -65569 sal eax, 11 shr edx, 11 and eax, 65536 and edx, 32 or eax, edx or eax, edi ret /* only works on little-endian! */ typedef union { struct { unsigned bit1: 1; unsigned bit2: 1; unsigned bit3: 1; unsigned bit4: 1; unsigned bit5: 1; unsigned bit6: 1; unsigned bit7: 1; unsigned bit8: 1; unsigned bit9: 1; unsigned bit10: 1; unsigned bit11: 1; unsigned bit12: 1; unsigned bit13: 1; unsigned bit14: 1; unsigned bit15: 1; unsigned bit16: 1; unsigned bit17: 1; unsigned bit18: 1; unsigned bit19: 1; unsigned bit20: 1; unsigned bit21: 1; unsigned bit22: 1; unsigned bit23: 1; unsigned bit24: 1; unsigned bit25: 1; unsigned bit26: 1; unsigned bit27: 1; unsigned bit28: 1; unsigned bit29: 1; unsigned bit30: 1; unsigned bit31: 1; unsigned bit32: 1; }; unsigned int n; } mybits; unsigned int swap(unsigned int n) { mybits foo; foo.n = n; unsigned tmp = foo.bit6; foo.bit6 = foo.bit17; foo.bit17 = tmp; return foo.n; }