我有以下示例代码:
uint64_t x, y;
x = ~(0xF<<24);
y = ~(0xFF<<24);
结果将是:
x=0xfffffffff0ffffff
y=0xfffff
有人能解释一下这个区别吗?为什么x要计算64位而y只计算32位?
我有以下示例代码:
uint64_t x, y;
x = ~(0xF<<24);
y = ~(0xFF<<24);
x=0xfffffffff0ffffff
y=0xfffff
有人能解释一下这个区别吗?为什么x要计算64位而y只计算32位?
默认操作是32位。
x=~(0xf<<24);
这段代码可以分解为以下步骤:
int32_t a;
a=0x0000000f;
a<<=24; // a=0x0f000000;
a=~a; // a=0xf0ffffff;
x=(uint64_t)a; // x = 0xfffffffff0ffffff;
同时,
y = ~(0xFF<<24);
int32_t a;
a=0x000000ff;
a<<=24; // a=0xff000000;
a=~a; // a=0x00ffffff;
x=(uint64_t)a; // x = 0x000000000ffffff;
int
,无论它是什么。 - Lundinuint64_t x, y;
x = ~(0xFULL<<24);
y = ~(0xFFULL<<24);
或者你可以这样做(我不知道这是否比上面的慢):
uint64_t x, y;
x = ~(uint64_t(0xF)<<24);
y = ~(uint64_t(0xFF)<<24);
然后:
x = 0xfffffffff0ffffff
y = 0xffffffff00ffffff
0x0f << 24
在int
类型下是一个正数,所以它会被符号扩展为一个正数,即0x00000000_0f000000
(下划线只是为了可读性,C语言不支持这种语法)。然后这个数会被反转成你看到的结果。0xff << 24
是负数,因此它的符号扩展方式也不同。您的程序存在未定义行为,因此可能会发生任何事情。
int
,它等同于signed int
。在这个特定的平台上,int
显然是32位。int
。int
,因此不会发生隐式类型提升。因此,<<操作的结果也是(有符号)int
。int
,所以一切正常。int
!在这里,调用了未定义的行为,可能会发生任何事情。ISO 9899:2011 6.5.7/4:
"E1 << E2 的结果是将 E1 左移 E2 位,空出的位用零填充。" /--/