[英]Is unsigned long int correct for this operation?
这是我的代码:
#include <stdio.h>
int main(int argc, char *argv[]) {
unsigned long int x = 0;
// trying to make x = 2,147,483,648
x = 1 << 31;
printf("%lu", x);
}
返回x =18446744071562067968。我读到unsigned long int应该达到4,294,967,296,所以为什么不能使用1 << 32将x设置为2,147,483,648?
如果您的系统具有32位整数,则1 << 31
会导致未定义的行为。 文字1
是带符号的int。
您需要执行无符号移位而不是有符号移位:
x = 1UL << 31;
我加了L
这样即使在16位系统上,代码仍然是正确的,这样做也没有什么害处。
非正式地,将1
移到符号位是不确定的。 正式文本可以在C11标准的6.5.7 / 4部分中找到:
E1 << E2
的结果是E1
左移E2
位位置; 空位用零填充。 [...]如果E1
具有带符号的类型和非负值,并且E1
×2
E2
在结果类型中可表示,则这就是结果值; 否则,行为是不确定的。
您的另一个问题“为什么我不能使用1 << 32
”被相同的引号覆盖。 1UL << 32
呢? 如果您的系统具有32位unsigned long
那么根据6.5.7 / 3,这也将是未定义的:
[...]如果右操作数的值为负或大于或等于提升的左操作数的宽度,则行为不确定
但是,如果您的系统具有64位unsigned long
它将可以工作。 为了避免在其他系统上编译时出现代码中断(此目标称为代码可移植性 ),您可以编写(uint64_t)1 << 32
(或1ULL << 32
)以保证工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.