unsigned long int是否适合此操作? [英] Is unsigned long int correct for this operation?

查看:95
本文介绍了unsigned long int是否适合此操作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的代码:

#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 is E1 left-shifted E2 bit positions; vacated bits are filled with zeros. [...] If E1 has a signed type and nonnegative value, and E1 × 2E2 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆