2

所以我试图解决这个问题:

给你一个随机的 32 位正整数,你要做的就是将第 3、4 和 5 位的位值与第 24、25 和 26 位的位值交换。

4

4 回答 4

6

假设这是一个您不想要明确解决方案的问题,这里有一个提示:使用 屏蔽有问题的位&,进行移位,然后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;
于 2012-09-13T19:27:36.597 回答
5

怎么样:

    // 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)

于 2012-09-13T19:33:41.413 回答
0

要解决这个问题,您可以使用按位属性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;

其余的都包含在现有的答案中。

于 2016-02-25T00:09:30.293 回答
0

我不喜欢给定答案的一件事是它们都是硬编码的。这是一个更通用的解决方案:

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,
}
于 2021-09-01T00:18:01.883 回答