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

我们需要提出一个方法,在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情况。 事实上,你正在为一个class次而not一个class次进行权衡。 没有太大的区别,代码更清晰,更优雅。

  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! 

我就是这样做的:

 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
  • 二进制或表达式的中间组合了初始值,现在我们想要设置的位已被清除,移位的半字节与最终解决方案一起出现。

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

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

你应该能够从这里找出细节。