所以我试图解决这个问题:
给你一个随机的 32 位正整数,你要做的就是将第 3、4 和 5 位的位值与第 24、25 和 26 位的位值交换。
假设这是一个您不想要明确解决方案的问题,这里有一个提示:使用 屏蔽有问题的位&
,进行移位,然后OR
使用按位|
。
您可以使用掩码“剪切”第 3、4 和 5 位,并使用0x00000034
掩码“剪切”第 24、25 和 26 位0x07000000
。
看看这个解决位反转问题的解决方案以获得灵感。
编辑:(回应“不是作业”评论)由于这不是作业,这里有一个更深入的解释:
unsigned int val = ... // your value
unsigned int bits_03_04_05 = val & 0x00000034;
unsigned int bits_24_25_26 = val & 0x07000000;
// Cut out "holes" at bits 3, 4, 5, 24, 25, and 26 of the original value
unsigned int res = val & ~(0x00000034 | 0x07000000);
// Put bits 3, 4, and 5 in place
res |= bits_03_04_05 << 21;
// Put bits 23, 24, and 25 in place
res |= bits_24_25_26 >> 21;
怎么样:
// snag the values from 3,4,5 (small) and 24,25,26 (large)
int small = value & (7 << 2), large = value & (7 << 23);
// remove the old values, and add in the new ones
value = (value ^ (small | large)) | (large >> 21) | (small << 21);
(将第 1 位计为 LSB;如果您的意思是第 0 位是 LSB,则将数字调整为 1)
要解决这个问题,您可以使用按位属性operator&
并operator|
在初始整数值和掩码之间应用它们。
假设您有一个初始值:
unsigned int val;// your value
你需要形成一个面具:
int setLSB = 1; // 00000001
int atPosition = 4;
// shift the set bit 4 positions to the left
int mask = setLSB << atPosition; // 00010000
然后用它来检索、清除和设置位值:
// get bit at position 4
unsigned int valueOfFourthBit = val & mask;
// clear bit at position 4 and assign to result
unsigned int res = val & ~(mask);
// put the value of the 4th bit at wanted position
int wantedPosition = 21;
res |= valueOfFourthBit << wantedPosition;
如果您需要一系列连续位,如您的情况 3,您可以执行以下操作:
int numberOfSetBits = 3;
int setLSBs = 0
for (int i =0; i < numberOfSetBits; ++i)
{
setLSBs += (int) Math.Pow(2, i);
}
setLSBs = 7; // 00000111
// and then the masks for getting 3,4,5 and 24,25,26 bits become
int smallPosition = 3;
int largePosition = 24;
int smallMask = setLSBs << smallPosition; // 0x00000034
int largeMask = setLSBs << largePosition; // 0x07000000;
其余的都包含在现有的答案中。
我不喜欢给定答案的一件事是它们都是硬编码的。这是一个更通用的解决方案:
int s32_Value = XYZ;
s32_Value = SwapBits(s32_Value, 1<<3, 1<<24);
s32_Value = SwapBits(s32_Value, 1<<4, 1<<25);
s32_Value = SwapBits(s32_Value, 1<<5, 1<<26);
int SwapBits(int s32_Value, int s32_Mask1, int s32_Mask2)
{
bool b_Bit1 = (s32_Value & s32_Mask1) != 0;
bool b_Bit2 = (s32_Value & s32_Mask2) != 0;
s32_Value &= ~s32_Mask1;
s32_Value &= ~s32_Mask2;
if (b_Bit1) s32_Value |= s32_Mask2;
if (b_Bit2) s32_Value |= s32_Mask1;
return s32_Value;
}
此函数也可用于包含位标志的枚举。例如,如果您想将 System.Windows.Forms.Control 的 Anchor 从左交换到右,反之亦然:
Ctrl.Anchor = (AnchorStyles)SwapBits((int)Ctrl.Anchor, (int)AnchorStyles.Left, (int)AnchorStyles.Right);
这是枚举的定义:
// Specifies how a control anchors to the edges of its container.
[Flags]
public enum AnchorStyles
{
// The control is not anchored to any edges of its container.
None = 0,
// The control is anchored to the top edge of its container.
Top = 1,
// The control is anchored to the bottom edge of its container.
Bottom = 2,
// The control is anchored to the left edge of its container.
Left = 4,
// The control is anchored to the right edge of its container.
Right = 8,
}