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:
Left shift the lower
bbits to the top (sizeof (d) - (b)is28bits in this case). When you left shift the lower bits become 0. With example data the value is0x8000000.The left followed by right shift clears the top
bbits, and the right followed by left shift clears the lowerbbits. With the example data the value is0x02345670. This equivalent bitwiseANDof the mask0x0ffffff0for a 32-bit number. The shift works for any unsigned integer type irregardless of size.Right shift the top
bbits to the bottom. When you right shift the upperbbits become zero. With the example data the value is0x00000001.
#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.
