# 如何交换给定 integer [32 位] 中的第一个和最后一个半字节

[英]How to swap first and last nibbles in given integer [32 bits]

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.然后循环并用 1 和打印。 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;
}
``````

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:给定一个无符号的 integer `d``b`位数，其中`b <= CHAR_BIT * sizeof(d) / 2`您可以通过这些组件的按位`OR`运算获得结果：

1. Left shift the lower `b` bits to the top ( `sizeof (d) - (b)` is `28` bits in this case).将较低的`b`位左移到顶部（ `sizeof (d) - (b)`在这种情况下为`28`位）。 When you left shift the lower bits become 0. With example data the value is `0x8000000` .当您左移时，低位变为 0。对于示例数据，该值为`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.左移后右移清除高`b`位，右移后左移清除低`b`位。 With the example data the value is `0x02345670` .对于示例数据，值为`0x02345670` This equivalent bitwise `AND` of the mask `0x0ffffff0` for a 32-bit number.这等效于 32 位数字的掩码`0x0ffffff0`的按位`AND` The shift works for any unsigned integer type irregardless of size.该班次适用于任何无符号 integer 类型，无论其大小如何。

3. Right shift the top `b` bits to the bottom.将高位`b`位右移到低位。 When you right shift the upper `b` bits become zero.当您右移时，高位`b`位变为零。 With the example data the value is `0x00000001` .对于示例数据，值为`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
``````

swap first and last nibbles in given integer (32 bits)交换给定 integer（32 位）中的第一个和最后一个半字节

OP's `decimalNumber = (decimalNumber>>28) | (decimalNumber<<28);` OP 的`decimalNumber = (decimalNumber>>28) | (decimalNumber<<28);` `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.同样移动 28 位会移动需要保留在原位的中间位。

• 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>` .对于固定大小的任务，请考虑使用`#include <stdint.h>`中的固定大小类型。

• Print data with %X to better see what is happening.使用 %X 打印数据以更好地查看发生了什么。

``````    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.无论是第一个还是最后一个都没有什么区别，因为它们被交换了。