You were extremely close;
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;
}
In fact, you can simplify the code at the expense of treating case which == 0
separately. In fact, you are trading-off an if
for a shift and a not
. Not much difference at all, and the code is much clearer and more elegant.
public static int setNibble(int num, int nibble, int which) {
int shiftNibble= nibble << (4*which) ;
int shiftMask= 0x0000000F << (4*which) ;
return ( num & ~shiftMask ) | shiftNibble ;
}
The idea of the mask is to completely clear the same 4 positions the nibble will occupy in the result. Otherwise, the position will contain garbage in those bits where the nibble has zeroes. For example
// 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!
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…