#include <stdio.h>
#include <limits.h>
int main()
{
unsigned long long a = 9223372036854775808; // a = 2^63
a = a & ~1;
printf("%llu\n", a);
printf("%d, %lld", INT_MAX, LLONG_MAX);
}
Output
9223372036854775808
2147483647, 9223372036854775807
This is the semantic of the ~
in C17(with my bold), 6.5.3.3.4.
The result of the ~ operator is the bitwise complement of its (promoted) operand (that is, each bit in the result is set if and only if the corresponding bit in the converted operand is not set). The integer promotions are performed on the operand, and the result has the promoted type. If the promoted type is an unsigned type, the expression ~E is equivalent to the maximum value representable in that type minus E.
This is the semantic of the unary &
in C17, 6.5.10.3.
The usual arithmetic conversions are performed on the operands.
a
is equal to 9223372036854775808
which is equal to 8000 0000 0000 0000(16)
.
An integer constant 1
without any suffix is the same as (int)1
. Therefore ~1
== ~(int)1
== FFFF FFFE(16)
(integer promotion doesn't happen by ~
).
The type of FFFF FFFE(16)
is converted to unsigned long long
at
a = 8000 0000 0000 0000(16) & FFFF FFFE(16)
by the usual arithmetic conversion. Therefore
a = 8000 0000 0000 0000(16) & FFFF FFFE(16)
==
a = 8000 0000 0000 0000(16) & 0000 0000 FFFF FFFE(16)
Finally,
a = a & ~1
==
a = 8000 0000 0000 0000(16) & FFFF FFFE(16)
==
a = 8000 0000 0000 0000(16) & 0000 0000 FFFF FFFE(16)
==
a = 0000 0000 0000 0000(16)
But the output says as if
a = a & ~1
==
a = 8000 0000 0000 0000(16) & FFFF FFFE(16)
==
a = 8000 0000 0000 0000(16) & FFFF FFFF FFFF FFFE(16)
==
a = 8000 0000 0000 0000(16)
My question is how the output is shown?