负整数>> 31 = -1不是1?

dga*_*ma3 7 c

所以,假设我有一个有符号整数(几个例子):

-1101363339 = 10111110 01011010 10000111 01110101 in binary.
-2147463094 = 10000000 00000000 01010000 01001010 in binary.
-20552      = 11111111 11111111 10101111 10111000 in binary.
Run Code Online (Sandbox Code Playgroud)

现在:-1101363339 >> 31例如,应该等于1对吗?但在我的电脑上,我得到-1.无论我选择什么负整数,如果x =负数,x >> 31 = -1.为什么?显然是二进制的,它应该是1.

Jef*_*den 19

每C99 6.5.7按位移位运算符:

如果E1具有带符号类型和负值,则结果值是实现定义的.

其中E1是班次表达式的左侧.所以它取决于你的编译器你会得到什么.

  • @aaronman:因为他的答案是唯一正确的答案. (9认同)
  • @ dgamma3它的实现已定义,因此OP的实现将其定义为算术移位 (3认同)
  • @ dgamma3:如果你要使用符号幅度或一个补码表示来实现带符号的算术,那么这种转换意味着什么?事实上,"没有自然的最佳选择"是它明确实现定义的原因.实现可以选择最适合的方法(例如,最接近硬件). (3认同)
  • @liori实际上他甚至不是OP的答案 (2认同)
  • @aaronman:就C语言而言,这是唯一正确的答案...... (2认同)
  • @aaronman:因为它是C.*你不能指望即使发生这种情况.* (2认同)
  • @ dgamma3:可能.它可能只是保持符号位并旋转其余部分.它可能会选择一个随机数.C完全由编译器决定,以指定移动负数时会发生什么. (2认同)
  • @aaronman:这个网站不只是对任何一个人都有用.它是关于对社区有用的.投票反映了这一点.对"个人"的价值反映在"接受"赏金上. (2认同)

aar*_*man 10

在大多数语言中,当您向右移动时,它会进行算术移位,这意味着它会保留最重要的位.因此,在您的情况下,您有二进制的所有1,十进制为-1.如果您使用,unsigned int您将获得您正在寻找的结果.

Per C 2011 6.5.7按位移位运算符:

结果E1 >> E2E1右移位E2位置.如果E1具有无符号类型 或者E1具有有符号类型和非负值,则结果的值是E1/ 2 E2的商的整数部分.如果E1具有有符号类型和负值,则结果值是实现定义的.

基本上,负有符号整数的右移是实现定义的,但大多数实现选择将其作为算术移位.

  • @aaronman:+1,但你应该停止抱怨你的答案的困境.如果您正在回答问题,那么您的答案通常不会被选中(即使您认为它更好). (8认同)

Cod*_*ice 5

您所看到的行为称为算术移位,即右移时扩展符号位.这意味着MSB将携带与原始符号位相同的值.换句话说,在左移操作之后,负数总是负的.

请注意,此行为是实现定义的,不能使用其他编译器来保证.

  • 不,在C中右移一个负值是实现定义的行为.另外,在C中,`>>>`运算符不存在. (5认同)