Search code examples
javabit-manipulation

Java bitwise AND incorrect output?


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?


Solution

  • 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 longs, and does not get sign-extended.