C++左移运算
C++ left shift operation
这是我的代码
int a=2147483647;
int b= a<<1;
cout<<"a="<<a<<", b="<<b;
我得到的输出是-
a=214783647, b=-2
a的二进制表示是
0111 1111 1111 1111 1111 1111 1111 1111
通过将其移动 1 位,它将改变符号位并将 LSB 替换为 0。因此,我认为答案将是 -ve,幅度将减去 1,即
-2147483646
但它给出的结果为 -2 。请解释。
嗯,后面的故事很长
由于int是有符号类型,也就是说第一位是符号,整个系统是二补码
所以 x = 0b 1111 1111 1111 1111 1111 1111 1111 0111 是 x = -9
例如 x = 0b 1111 1111 1111 1111 1111 1111 1111 1111 是 x = -1 和 x = 0b 0000 0000 0000 0000 0000 0000 0000 0010 是 2
详细了解 Two complement。
[expr.shift]/1 The value of E1 << E2
is E1
left-shifted E2
bit positions; vacated bits are zero-filled. ... 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.
强调我的。您的程序表现出未定义的行为。
编辑:经过仔细考虑,我不再认为这是未定义的行为。 2147483647*2
确实适合 unsigned int
、"the corresponding unsigned type" 或 int
。它到 int
的转换不是未定义的,而只是实现定义的。对于使用二进制补码的实现来定义此转换是完全合理的,因此 2147483647*2 == -2
,只需重新解释位模式,正如其他答案所解释的那样。
这是因为您的计算机对有符号值使用 2 补码。
无符号移位值是 0xFFFFFFFE
,即 2 补码中的 -2,而不是 -2147483647
.
移位是在 C 中定义的实现。
顺便说一句,-2147483647
在 CPU 上是 0x80000001
。
这是我的代码
int a=2147483647;
int b= a<<1;
cout<<"a="<<a<<", b="<<b;
我得到的输出是- a=214783647, b=-2
a的二进制表示是
0111 1111 1111 1111 1111 1111 1111 1111
通过将其移动 1 位,它将改变符号位并将 LSB 替换为 0。因此,我认为答案将是 -ve,幅度将减去 1,即 -2147483646 但它给出的结果为 -2 。请解释。
嗯,后面的故事很长
由于int是有符号类型,也就是说第一位是符号,整个系统是二补码
所以 x = 0b 1111 1111 1111 1111 1111 1111 1111 0111 是 x = -9 例如 x = 0b 1111 1111 1111 1111 1111 1111 1111 1111 是 x = -1 和 x = 0b 0000 0000 0000 0000 0000 0000 0000 0010 是 2
详细了解 Two complement。
[expr.shift]/1 The value of
E1 << E2
isE1
left-shiftedE2
bit positions; vacated bits are zero-filled. ... 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.
强调我的。您的程序表现出未定义的行为。
编辑:经过仔细考虑,我不再认为这是未定义的行为。 2147483647*2
确实适合 unsigned int
、"the corresponding unsigned type" 或 int
。它到 int
的转换不是未定义的,而只是实现定义的。对于使用二进制补码的实现来定义此转换是完全合理的,因此 2147483647*2 == -2
,只需重新解释位模式,正如其他答案所解释的那样。
这是因为您的计算机对有符号值使用 2 补码。
无符号移位值是 0xFFFFFFFE
,即 2 补码中的 -2,而不是 -2147483647
.
移位是在 C 中定义的实现。
顺便说一句,-2147483647
在 CPU 上是 0x80000001
。