Java gives incorrect output when using Bitwise AND:
class Main
{
public static void main(String[] args)
{
long a = -26000;
System.out.printf("%X\n", a);
// upper 32-bits are 0 (implicitly)
System.out.printf("%X\n", (a & 0xFFFFFFFF));
// upper 32-bits are 0 (explicitly specified)
System.out.printf("%X\n", (a & 0x00000000FFFFFFFF));
}
}
/*
Output:
FFFFFFFFFFFF9A70
FFFFFFFFFFFF9A70
FFFFFFFFFFFF9A70
*/
Code link: https://godbolt.org/z/Y8q3MhdK5
Any ideas why?
0xFFFFFFFF
and 0x00000000FFFFFFFF
are both int
literals, representing the value -1.
When &
is applied on a long
and an int
, the int
undergoes numeric promotion, and gets converted to a long
.
Otherwise, if any expression is of type long, then the promoted type is long, and other expressions that are not of type long undergo widening primitive conversion to
long
.
During this conversion, the value is sign-extended,
A widening conversion of a signed integer value to an integral type T simply sign-extends the two's-complement representation of the integer value to fill the wider format.
so you still get the same value (-1) as a long
. -1's bits are all 1, so you get the same result.
To get the intended result, add the L
suffix to these literals, so they are actually long
s, and does not get sign-extended.