#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);
}
输出
9223372036854775808
2147483647, 9223372036854775807
这是~
C17(用我的粗体字)6.5.3.3.4 中的语义。
~ 运算符的结果是其(提升)操作数的按位补码(即,当且仅当未设置转换操作数中的相应位时,结果中的每个位都被设置)。整数提升在操作数上执行,结果具有提升的类型。如果提升的类型是无符号类型,则表达式 ~E 等价于该类型中可表示的最大值减去 E。
这是&
C17 6.5.10.3 中一元的语义。
通常的算术转换是在操作数上执行的。
a
等于9223372036854775808
等于8000 0000 0000 0000(16)
。
没有任何后缀的整数常量1
与(int)1
. 因此~1
== ~(int)1
== FFFF FFFE(16)
(整数提升不会发生在~
)。
的类型通过通常的算术转换FFFF FFFE(16)
转换为unsigned long long
at 。
a = 8000 0000 0000 0000(16) & FFFF FFFE(16)
因此
a = 8000 0000 0000 0000(16) & FFFF FFFE(16)
==
a = 8000 0000 0000 0000(16) & 0000 0000 FFFF FFFE(16)
最后,
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)
但是输出说好像
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)
我的问题是如何显示输出?