Home > OS >  How to swap first and last nibbles in given integer [32 bits]
How to swap first and last nibbles in given integer [32 bits]

Time:01-26

Suppose :

No = 77
77 in binary [32 bits] : 0000 0000 0000 0000 0000 0000 0100 1101

I have to swap first and last nibble:

i.e :                    1101 0000 0000 0000 0000 0000 0100 0000

I was doing something like this:

no << 32 | no >> 32

Then in a loop anding it with 1 and printing. But it does not work out.

#include<stdio.h>

int main()
{

    int decimalNumber;
    printf("Enter your decimal number: ");
    scanf("%d", &decimalNumber);
    int i, j;
    
    /* Binary conversion */
    for(i=31;i>=0;i--)
    {

        printf("%d", (decimalNumber >> i) & 1);
    }
    printf("\n");
    printf("After nibble swapping: \n");
    /* Nibble swapping */
    decimalNumber = (decimalNumber>>28) | (decimalNumber<<28);
    for(i=31;i>=0;i--)
    {
        printf("%d",((decimalNumber>>i)&1 ? 1 : 0));
    }
    printf("\n");
    return 0;
}

CodePudding user response:

Given an unsigned integer d and b number of bits where b <= CHAR_BIT * sizeof(d) / 2 you obtain the result by bitwise OR of these components:

  1. Left shift the lower b bits to the top (sizeof (d) - (b) is 28 bits in this case). When you left shift the lower bits become 0. With example data the value is 0x8000000.

  2. The left followed by right shift clears the top b bits, and the right followed by left shift clears the lower b bits. With the example data the value is 0x02345670. This equivalent bitwise AND of the mask 0x0ffffff0 for a 32-bit number. The shift works for any unsigned integer type irregardless of size.

  3. Right shift the top b bits to the bottom. When you right shift the upper b bits become zero. With the example data the value is 0x00000001.

#include <limits.h>
#include <stdio.h>
#include <stdint.h>

#define SWAP_BITS(d, b) \
    /* 1 */ (d) << CHAR_BIT * sizeof (d) - (b) |\
    /* 2 */ (d) << (b) >> (b) >> (b) << (b) |\
    /* 3 */ (d) >> CHAR_BIT * sizeof (d) - (b)

int main() {
    uint32_t d = 0x12345678;
    printf("%x\n%x\n", d, SWAP_BITS(d, 4));
}

and the outcome is:

82345671

CodePudding user response:

swap first and last nibbles in given integer (32 bits)

OP's decimalNumber = (decimalNumber>>28) | (decimalNumber<<28); fails as the | or's the data, not replace it. Also shifting by 28 shifts the middle bits, which need to remain in place.


  • Use unsigned types to not shift into or out of the sign bit.

  • For a fixed sized tasks, consider using fixed sized types from #include <stdint.h>.

  • Print data with %X to better see what is happening.

    uint32_t uvalue = decimalNumber;
    printf("Before %lu\n", (unsigned long) uvalue);   // In decimal
    printf("Before 0x%lX\n", (unsigned long) uvalue); // In hexadecimal

    // Get first (most significant) and last (least significant) nibble.
    uint32_t first_nibble = uvalue >> (32-4);
    uint32_t last_nibble = uvalue & 0xF;

    // zero out the first and last nibble.
    uvalue &= 0x0FFFFFF0; 
    // Now "or" in the replacement nibbles.
    uvalue |= first_nibble;
    uvalue |= last_nibble << (32-4);

    printf("After 0x%lX\n", (unsigned long) uvalue);
    printf("After %lu\n", (unsigned long) uvalue);

For those who like one-liners

printf("After %lu\n", (unsigned long) (
    (((uint32_t) decimalNumber) & 0xF) << 28) |
    ((uint32_t) decimalNumber) & 0x0FFFFFF0) |
    ((uint32_t) decimalNumber) >> 28) |
    )); 

Some would consider the first nibble as the least significant nibble. Whatever is first or last makes little difference here as they are swapped.

  • Related