Swapping nibbles

Thread Starter

Embededd

Joined Jun 4, 2025
131
I came across two different ways to swap nibbles in a byte.

The first version (which I found online https://www.geeksforgeeks.org/dsa/swap-two-nibbles-byte/ ) uses masking:

C:
unsigned char swapNibbles(unsigned char x)
{
    return ((x & 0x0F) << 4) | ((x & 0xF0) >> 4);
}
And then I wrote my own version without any masks on my laptop

C:
#include <stdio.h>
#include <stdint.h>

int main() {
    uint8_t byte = 8;                           // 0000 1000 = 8
    byte = (byte << 4) | (byte >> 4);           // 1000 0000 = 128
    printf("Swap nibble: %u\n", byte);
    return 0;
}
I didn’t use any masking here and the output matches what I expect.

Are there any cases where my non-masked version would fail, or both are always equivalent for 8-bit values?

Is masking really necessary ?
 

panic mode

Joined Oct 10, 2011
4,864
your version has no range check or anything to ensure that handled value is really 8 bit. it is strictly relying on keen eye of the programmer to keep track of things. that is less than ideal.

what if your 'byte' variable is declared as something else?
 

Futurist

Joined Apr 8, 2025
721
I came across two different ways to swap nibbles in a byte.

The first version (which I found online https://www.geeksforgeeks.org/dsa/swap-two-nibbles-byte/ ) uses masking:

C:
unsigned char swapNibbles(unsigned char x)
{
    return ((x & 0x0F) << 4) | ((x & 0xF0) >> 4);
}
And then I wrote my own version without any masks on my laptop

C:
#include <stdio.h>
#include <stdint.h>

int main() {
    uint8_t byte = 8;                           // 0000 1000 = 8
    byte = (byte << 4) | (byte >> 4);           // 1000 0000 = 128
    printf("Swap nibble: %u\n", byte);
    return 0;
}
I didn’t use any masking here and the output matches what I expect.

Are there any cases where my non-masked version would fail, or both are always equivalent for 8-bit values?

Is masking really necessary ?
Your code works fine for any value of the variable 'byte'.
 

BobTPH

Joined Jun 5, 2013
11,463
your version has no range check or anything to ensure that handled value is really 8 bit
The declaration of byte as uint8_t guarantees that it fits in a byte. Had he declared it unsigned char, like the other function, I would agree with you in pedagogical mode.
 

WBahn

Joined Mar 31, 2012
32,702
I came across two different ways to swap nibbles in a byte.

The first version (which I found online https://www.geeksforgeeks.org/dsa/swap-two-nibbles-byte/ ) uses masking:

C:
unsigned char swapNibbles(unsigned char x)
{
    return ((x & 0x0F) << 4) | ((x & 0xF0) >> 4);
}
And then I wrote my own version without any masks on my laptop

C:
#include <stdio.h>
#include <stdint.h>

int main() {
    uint8_t byte = 8;                           // 0000 1000 = 8
    byte = (byte << 4) | (byte >> 4);           // 1000 0000 = 128
    printf("Swap nibble: %u\n", byte);
    return 0;
}
I didn’t use any masking here and the output matches what I expect.

Are there any cases where my non-masked version would fail, or both are always equivalent for 8-bit values?

Is masking really necessary ?
A char data type is not required to be 8-bits, it is only required to be at least eight bits. So the first example needs to mask off the higher-order bits to be safe.

Also, both examples require that the variable be of unsigned type, since right-shifting a signed type invoked implementation-defined behavior. In most implementations, an arithmetic right shift is performed, but this is not required. Both examples above rely on the right shift being a logical one.
 

Thread Starter

Embededd

Joined Jun 4, 2025
131
So I am right in saying that my version does correctly swap the nibbles as long as the variable is an uint8_t (so exactly 8 bits wide and unsigned)
 

Futurist

Joined Apr 8, 2025
721
So I am right in saying that my version does correctly swap the nibbles as long as the variable is an uint8_t (so exactly 8 bits wide and unsigned)
Some C implementations provide rotate intrinsics, so a rotate by 4 bits would also do this nybble swap.
 

WBahn

Joined Mar 31, 2012
32,702
Some C implementations provide rotate intrinsics, so a rotate by 4 bits would also do this nybble swap.
Since most processors have rotate instructions, another option is to use embedded assembly instructions in your C code. That would ensure that it uses the processor's capabilities, though it also locks that code to that processor.
 
Top