左移一个整数32位

Left shift an integer by 32 bits

本文关键字:一个 整数 32位 左移      更新时间:2023-10-16

在GCC下,如果num1s == 0,以下代码总是返回<<的左操作数:

0xFFFFFFFFu << (32-num1s);

阅读后,为什么't左位移位,"<<",对于32位整数,当使用超过32次时,不能正常工作?在David Heffernan引用的标准中,如果左操作数为unsigned,则它是一个定义操作。只有当E1(左操作数)具有带符号类型且非负值时,才可能导致未定义行为。

如果标准明确规定,如果移位量大于类型包含的位数,则为未定义行为,谁能解释一下?

§5.8移运算符

操作结果的类型为提升后的左操作数的类型。如果右操作数为负,或者大于等于提升后的左操作数的位长度,则不定义此行为。

E1 << E2的值为E1左移E2位;空出的位是零填充的。如果E1是unsigned类型,则结果的值是E1 × 2E2,比结果类型中可表示的最大值多取1。否则,如果E1为有符号类型且非负值,且E1×2E2在结果类型中可表示,则该值为结果值;否则,行为是未定义的。

CoryKramer已经回答了为什么它是标准的未定义行为。

我将试着解释它在实际情况下是如何工作的。c++编译器通常将32位整数的<<>>操作符实现为汇编指令,而不检查操作数范围。这意味着结果取决于特定于处理器的移位指令的实现。

例如,32位SHL/SHR/SAL/SAL指令的Intel处理器规范说:

目的操作数可以是寄存器或内存位置。的count操作数可以是立即值或寄存器CL。计数是掩码为5位,限制计数范围为0 ~ 31。

这意味着a << b在Intel处理器上变成了a << (b & 0x1f)。因此移位32位意味着不移位。

但是你不应该依赖这些信息!编译器还可以优化代码并使用矢量指令实现移位操作符。在这种情况下,即使处理器规范也未指定该行为。

相关文章: