Home > Net >  Reverse nibbles of a hexadecimal number in C
Reverse nibbles of a hexadecimal number in C

Time:01-28

What would be the fastest way possible to reverse the nibbles (e.g digits) of a hexadecimal number in C ?

Here's an example of what I mean : 0x12345 -> 0x54321

Here's what I already have:

unsigned int rotation (unsigned int hex) {
    unsigned int result = 0;

    while (hex) {
        result = (result << 4) | (hex & 0xF);
        hex >>= 4;
    }

    return result;
}

CodePudding user response:

This problem can be split into two parts:

  • Reverse the nibbles of an integer. Reverse the bytes, and swap the nibble within each byte.
  • Shift the reversed result right by some amount to adjust for the "variable length". There are std::countl_zero(x) & -4 (number of leading zeroes, rounded down to a multiple of 4) leading zero bits that are part of the leading zeroes in hexadecimal, shifting right by that amount makes them not participate in the reversal.

For example, using some of the new functions from <bit>:

#include <stdint.h>
#include <bit>

uint32_t reverse_nibbles(uint32_t x) {
    // reverse bytes
    uint32_t r = std::byteswap(x);
    // swap adjacent nibbles
    r = ((r & 0x0F0F0F0F) << 4) | ((r >> 4) & 0x0F0F0F0F);
    // adjust for variable-length of input
    int len_of_zero_prefix = std::countl_zero(x) & -4;
    return r >> len_of_zero_prefix;
}

That requires C 23 for std::byteswap which may be a bit optimistic, you can substitute it with some other byteswap.

Easily adaptable to uint64_t too.

CodePudding user response:

i would do it without loops based on the assumption that the input is 32 bits

  result = (hex & 0x0000000f) << 28
         | (hex & 0x000000f0) << 20
         | (hex & 0x00000f00) << 12  
  ....

dont know if faster, but I find it more readable

  • Related