【问题标题】:Exchanging one bit with another in a integer, code does not work在整数中与另一位交换一位,代码不起作用
【发布时间】:2014-02-21 09:11:02
【问题描述】:

编写一个程序,将位置 3、4 和 5 上的位的值与给定的位置 24、25 和 26 上的位交换 32 位无符号整数。

所以上面是练习,下面是我的工作。

int number = 28;                                //number                         -0001 1100    28
int bit3 = (number >> 3) & 1;                   //obtain bit 3rd bit from left   -0000 0001     1
int bit3return = bit3 << 3;                     //return bit to possition        -0000 1000     8
int numberReturn = number & (~(bit3return));    //number with bit place reversed -0001 0100    20

int number2 = 20;                               //number                         -0001 0100    20
int bit3Return = 1 << 3;                        //return bit to possition        -0000 1000     8
int numberReturn2 = number2 + bit3Return;       //number with bit place reversed -0001 0100    28

这是我的最终代码。

Console.WriteLine("Enter a number to be modified:");
int num = int.Parse(Console.ReadLine());

int b3 = (num >> 3) & 1;
int b4 = (num >> 4) & 1;
int b5 = (num >> 5) & 1;
int b24 = (num >> 24) & 1;
int b25 = (num >> 25) & 1;
int b26 = (num >> 26) & 1;

num = num & (~(1 << b24)) | (b3 << 24);
num = num & (~(1 << b3)) | (b24 << 3);
num = num & (~(1 << b25)) | (b4 << 25);
num = num & (~(1 << b4)) | (b25 << 4);
num = num & (~(1 << b26)) | (b5 << 26);
num = num & (~(1 << b5)) | (b26 << 5);

Console.WriteLine(num);

问题是,它不起作用:

我输入56,即:

  • 0000 0000 0000 0000 0000 0000 0011 1000

输出应该是 117440512 即:

  • 0000 0111 0000 0000 0000 0000 0000 0000

但是我得到 117440568 是:

  • 0000 0111 0000 0000 0000 0000 0011 1000

如果我输入 117440512 我得到相同的输出,所以 0 变成 1 但 1 不会变成 0。请帮忙。

【问题讨论】:

  • 您添加了新值但没有删除旧值? (异或/或)
  • 您可能要考虑可以在一次操作中提取所有 3 个低位(或所有 3 个高位)。而且您不必将它们向下移动到位位置 0。

标签: c# bit-manipulation bitwise-operators


【解决方案1】:

您的代码过于复杂。考虑同时操作所有三个位。算法应该如下:

  1. 通过使用… 0011 1000 屏蔽来分隔位 3、4、5;
  2. 左移 21 到位置 24、25、26;
  3. 通过使用… 0111 0000 … 屏蔽来分隔位 24、25、26;
  4. 右移 21 到位置 3、4、5;
  5. 通过与 '...1000 1111 ... 1100 01111' 进行 AND 运算,屏蔽原始变量中的 3、4、5、24、25、26;
  6. 通过将 (2) 和 (4) 的临时结果与 (5) 的结果进行 OR 运算来混合它们。

实际代码实现留给读者。

【讨论】:

    【解决方案2】:

    例如输入 x

    x = 1234567890              // == 0100 1001 1001 0110 0000 0010 1101 0010
    

    获取上下掩码

    umask = 7 << 24             // == 0000 0111 0000 0000 0000 0000 0000 0000
    lmask = 7 << 3              // == 0000 0000 0000 0000 0000 0000 0011 1000
    

    获取我们想要交换的位

    y = x & umask               // == 0000 0001 0000 0000 0000 0000 0000 0000
    z = x & lmask               // == 0000 0000 0000 0000 0000 0000 0001 0000
    

    将 y 移到较低的位置

    y = y >> (24 - 3)           // == 0000 0000 0000 0000 0000 0000 0000 1000
    

    将 z 移到更高的位置

    z = z << (24 - 3)           // == 0000 0010 0000 0000 0000 0000 0000 0000
    

    屏蔽旧值

    x = x & ~( umask | lmask )  // == 0100 1000 1001 0110 0000 0010 1100 0010
    

    输入新值

    x = x | y | z               // == 0100 1010 1001 0110 0000 0010 1100 1010
    

    【讨论】:

      【解决方案3】:

      给定:

      int b24 = (num >> 24) & 1;
      

      表示b24只能包含0或1。表示:

      num & (~(1 << b24))
      

      将清除num 的第 0 位或第 1 位。然后:

      | (b3 << 24);
      

      要么设置第 24 位(如果 b3 为 1),要么将其保留为当前具有的任何值(如果 b3 为 0)。你可能想要:

      num & (~(1 << 24))
      

      清除数字的第 24 位。

      (对所有剩余的行应用相同的逻辑。每行重复清除num 的位 0 或 1,然后尝试设置不同位的值)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-10-23
        • 2022-07-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-10-05
        相关资源
        最近更新 更多