了解 C++14 中有符号类型的按位左移
Understanding bitwise left shift on signed types in C++14
根据cppreference,
For signed a
, the value of a << b
is a * 2^b
if it is
representable [in the unsigned version of the (since C++14)] return
type [(which is then converted to signed: this makes it legal to
create INT_MIN
as 1 << 31
) (since C++14)], otherwise the behavior
is undefined.
我不太明白这个规范。 如果它在 return 类型的无符号版本中是可表示的 究竟是什么意思?它仅适用于有符号值非负的情况吗? INT_MIN << 1
和 -1 << 31
定义明确吗?
如果我们查看 C++14 标准的源代码,我们会发现以下内容(突出显示有关无符号类型的部分):
The value of E1 << E2
is E1
left-shifted E2
bit positions; vacated bits are zero-filled. If E1
has an unsigned type, the value of the result is E1 × 2
E2
, reduced modulo one more than the maximum value representable in the result type. Otherwise, if E1
has a signed type and non-negative value, and E1 × 2
E2
is representable in the corresponding unsigned type of the result type, then that value, converted to the result type, is the resulting value; otherwise, the behavior is undefined.
对于std::numeric_limits<int>::digits
为31的平台,执行1 << 31
是合法的。 unsigned int
中的结果值为 0x80000000
或 2147483648
。但是,该数字超出了此类平台的 int
的有效值范围。然而,当被视为二进制补码表示时,该位模式 int
等于 -2147483648
,这与此类平台的 INT_MIN
相同。
如果你使用
int a = 2 << 31;
您调用了未定义的行为,因为 2 * 2
31
在该平台中无法表示为 unsigned int
。
Are INT_MIN << 1 and -1 << 31 well-defined?
不,他们不是。按位左移负数是未定义的行为。请注意在上面突出显示的文本中使用 非负值 。
根据cppreference,
For signed
a
, the value ofa << b
isa * 2^b
if it is representable [in the unsigned version of the (since C++14)] return type [(which is then converted to signed: this makes it legal to createINT_MIN
as1 << 31
) (since C++14)], otherwise the behavior is undefined.
我不太明白这个规范。 如果它在 return 类型的无符号版本中是可表示的 究竟是什么意思?它仅适用于有符号值非负的情况吗? INT_MIN << 1
和 -1 << 31
定义明确吗?
如果我们查看 C++14 标准的源代码,我们会发现以下内容(突出显示有关无符号类型的部分):
The value of
E1 << E2
isE1
left-shiftedE2
bit positions; vacated bits are zero-filled. IfE1
has an unsigned type, the value of the result isE1 × 2
E2
, reduced modulo one more than the maximum value representable in the result type. Otherwise, ifE1
has a signed type and non-negative value, andE1 × 2
E2
is representable in the corresponding unsigned type of the result type, then that value, converted to the result type, is the resulting value; otherwise, the behavior is undefined.
对于std::numeric_limits<int>::digits
为31的平台,执行1 << 31
是合法的。 unsigned int
中的结果值为 0x80000000
或 2147483648
。但是,该数字超出了此类平台的 int
的有效值范围。然而,当被视为二进制补码表示时,该位模式 int
等于 -2147483648
,这与此类平台的 INT_MIN
相同。
如果你使用
int a = 2 << 31;
您调用了未定义的行为,因为 2 * 2
31
在该平台中无法表示为 unsigned int
。
Are INT_MIN << 1 and -1 << 31 well-defined?
不,他们不是。按位左移负数是未定义的行为。请注意在上面突出显示的文本中使用 非负值 。