我们需要提出一种在int中设置4位半字节的方法
输出应如下所示:

 setNibble(0xAAA5, 0x1, 0); // => 0xAAA1
 setNibble(0x56B2, 0xF, 3); // => 0xF6B2

这就是我写的

但是有什么错误我无法弄清楚
setNibble(FFFF, 0, 0): Expected: FFF0 Result: FF00
setNibble(FFFF, 6, 1): Expected: FF6F Result:  6FF
setNibble(1312, E, 1): Expected: 13E2 Result:  E12

更新:我已经放下代码以防万一。但基本上答案很明确,上面有很多很棒的答案。

最佳答案

你非常亲密;

    public static int setNibble(int num, int nibble, int which)
    {
        int output;
        if(which ==0)
        {
            output = (num & /*65280*/ 0xFFFFFFF0 ) | nibble;
        }
        else
        {
            int shiftNibble = nibble << (4*which) ;
            int shiftMask = 0x0000000F << (4*which) ;
            output = (num & ~shiftMask) | shiftNibble ;
        }
        return output;
    }

实际上,您可以简化代码,但要以分别处理大小写which == 0为代价。实际上,您需要权衡if和shift以及not。根本没有什么区别,并且代码更清晰,更优雅。
    public static int setNibble(int num, int nibble, int which) {
        int shiftNibble= nibble << (4*which) ;
        int shiftMask= 0x0000000F << (4*which) ;
        return ( num & ~shiftMask ) | shiftNibble ;
    }

遮罩的想法是完全清除小节将占据结果的相同4个位置。否则,该位置将在半字节为零的那些位中包含垃圾。例如
    // Nibble           77776666555544443333222211110000
    num=              0b01001010111101010100110101101010 ;
    nibble=           0b0010 ;  // 2
    which=            3 ;
    shiftNibble=      0b00000000000000000010000000000000 ;
    shiftMask=        0b00000000000000001111000000000000 ;
    num=              0b01001010111101010100110101101010 ;
    ~shiftMask=       0b11111111111111110000111111111111 ;
    num & ~shiftMask= 0b01001010111101010000110101101010 ;
    //                                  ~~~~  Cleared!
    ( num & ~shiftMask )
      | nibble        0b01001010111101010010110101101010 ;
    //                                  ~~~~  Fully set; no garbage!

07-25 23:35