首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >左移溢出

左移溢出
EN

Stack Overflow用户
提问于 2015-10-01 22:53:32
回答 1查看 1.1K关注 0票数 0

我有一个简单的程序,其中我有几个宏位操作。

其中一个宏转换为

代码语言:javascript
运行
复制
unsigned long val = 1 << 0x1f;

在这里,我得到的输出是

代码语言:javascript
运行
复制
val = 0xffffffff80000000;

我知道这是某种int溢出。我对最终结果的那一部分感到困惑。为什么结果会成为我所得到的结果呢?

(我在这里理解,因为某种原因,1被视为int,当左移位使其为负int时。但我对这种类型的铸造感到困惑。)

EN

回答 1

Stack Overflow用户

发布于 2015-10-01 22:55:21

1是一个有符号整数,因此在溢出的情况下,它是未定义的行为。

根据标准(强调地雷):

E1 << E2的结果是E1左移的E2位位置;空出的位充满了零。如果E1具有无符号类型,则结果的值为E1 × 2E2,减少的模值比结果类型中可表示的最大值多一个。如果E1 × 2E2具有有符号类型和非负值,并且E1 × 2E2在结果类型中是可表示的,那么这就是结果值;否则,行为是未定义的。

相反,尝试unsigned long1ul

代码语言:javascript
运行
复制
unsigned long val = 1ul << 0x1f

(我在这里理解,因为某种原因,1被视为int,而当左移位使它成为负整数时)。但我对这种类型的铸造感到困惑。)

实际上,如果将符号位设置为1 (但是,按照标准,它是UB),实际上可能会发生这种情况。

尽管如此,让我们考虑一个法律案例(我使用了shortint,因为intlong在我的系统上具有相同的大小):

代码语言:javascript
运行
复制
                        // on my system
short int s = SHRT_MIN; // 0x8000
unsigned int i = s;     // 0xffff8000

标准的以下部分对此作了澄清:

6.3.1.3有符号整数和无符号整数 当具有整数类型的值转换为_Bool以外的另一个整数类型时,如果该值可以由新类型表示,则它将保持不变。 否则,如果新类型是无符号的,则通过重复增减一个比在新类型中表示的最大值更多的值来转换值,直到该值位于新类型的范围内为止。

(如果我正确地解释它),因为我们不能用无符号类型表示负值,所以我们将UINT_MAX + 1添加到SHRT_MIN中(用纯数学的术语,而不考虑溢出):

代码语言:javascript
运行
复制
UINT_MAX + 1 + SHRT_MIN // 0xffff8000
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32898056

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档