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