unsigned long int是否适合此操作? [英] 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?
It's returning that x = 18446744071562067968. I read that unsigned long int should go up to 4,294,967,296, so why can't I use 1 << 32 to set x equal to 2,147,483,648?
推荐答案
1 << 31
会导致未定义的行为.文字1
是带符号的int.
1 << 31
causes undefined behaviour, if your system has 32-bit ints. The literal 1
is a signed int.
您需要执行无符号班次而不是有符号班次:
You need to do an unsigned shift instead of a signed shift:
x = 1UL << 31;
我添加了L
,以便即使在16位系统上,代码仍然是正确的,这样做也没有什么害处.
I added L
so that the code is still correct even on a 16-bit system, and it doesn't hurt to do so.
非正式地,将1
移入符号位是不确定的.正式文本可以在C11标准的6.5.7/4部分中找到:
Informally, shifting a 1
into the sign bit is undefined. The formal text can be found in section 6.5.7/4 of the C11 standard:
E1 << E2
的结果是E1
左移E2
位的位置;空位用零填充. [...]如果E1
具有带符号的类型且非负值,并且E1
×2
E2
在结果类型中可表示,则它是结果值;否则,行为是不确定的.
The result of
E1 << E2
isE1
left-shiftedE2
bit positions; vacated bits are filled with zeros. [...] IfE1
has a signed type and nonnegative value, andE1
×2
E2
is representable in the result type, then that is the resulting value; otherwise, the behavior is undefined.
您的另一个问题为什么我不能使用1 << 32
"被同一引号覆盖.那1UL << 32
呢?如果您的系统具有32位unsigned long
,则根据6.5.7/3,该值也将是未定义的:
Your other question, "why can't I use 1 << 32
" is covered by that same quote. What about 1UL << 32
? If your system has 32-bit unsigned long
then this would also be undefined according to 6.5.7/3:
[...]如果右操作数的值为负或大于或等于提升的左操作数的宽度,则行为是不确定的
[...] If the value of the right operand is negative or is greater than or equal to the width of the promoted left operand, the behavior is undefined
但是如果您的系统具有64位unsigned long
,它将可以正常工作.为了避免在其他系统上编译时出现代码中断(此目标称为代码可移植性),您可以编写保证可以正常工作的(uint64_t)1 << 32
(或1ULL << 32
).
But it would work if your system had 64-bit unsigned long
. To avoid having your code break when compiled on a different system (this goal is known as code portability) you could write (uint64_t)1 << 32
(or 1ULL << 32
) which is guaranteed to work.
这篇关于unsigned long int是否适合此操作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!