在int类型中设置4位半字节

时间:2013-09-03 03:53:06

标签: java bit-manipulation

我们需要提出一种在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 

更新:我已经放下了代码。但基本上答案非常明确,上面有很多很好的答案。

3 个答案:

答案 0 :(得分:4)

你非常接近;

    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交换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!

答案 1 :(得分:3)

我就是这样做的:

public static int setNibble(int word, int nibble, int whichNibble)
{
    int shift = whichNibble * 4;
    return (word & ~(0xf << shift)) | (nibble << shift);
}

让我们分解一下:

  • shift是您需要移位以将半字节的4位置于整数内的正确位置的位数。如果要定位半字节0,shift为0;蚕食1是4; 8为半字节2;等等。
  • (0xf << shift)是一个二进制掩码,其中半字节占用的每个位都有1。如果你想要半字节1,这将是0b0000 0000  1111  0000(为了简洁起见,在16位整数中)。
  • ~(0xf << shift)是原始参数中保持位的二进制掩码。假设您想再次替换半字节1,此掩码为0b1111 1111 0000 1111
  • word & ~(0xf << shift)清除我们要从word替换的位。
  • (nibble << shift)是您正在设置的半字节的二进制模式。如果您的半字节值为0b1001,则一旦移动,它就会变为0b0000 0000  1001  0000
  • 表达式的二进制或中间组合了初始值,现在我们想要设置的位已被清除,而移位的半字节将与最终解决方案一起提供。

答案 2 :(得分:0)

你正在以错误的数量转移你的蚕食。每个“哪个”需要移位4位;那么你需要替换该位置的位(首先将这些位设置为零,然后将OR设置为移位的半字节)。像这样:

shiftIt = 4 * which;
mask = 0xf << shiftIt;
num = num & ~mask;
num = num + (n << shiftIt);

你应该可以从这里找出细节。