我知道>>
对有符号整数的行为可能依赖于实现(具体来说,当左操作数为负数时)。
其他人:~
,>>
,&
,^
,|
?
当他们的操作数是内置类型(short
,int
,long
,long long
)的有符号整数时,结果保证是相同的(就位而言)内容)好像他们的类型是未签名的?
答案 0 :(得分:42)
对于负操作数,<<
具有未定义的行为,>>
的结果是实现定义的(通常为“算术”右移)。 <<
和>>
在概念上不是按位运算符。它们是算术运算符,相当于乘法或除以它们定义明确的操作数的2的适当幂。
对于真正的按位运算符^
,~
,|
和&
,它们对(可能提升的)类型中的值的位表示进行操作操作数。对于每个可能选择的有符号表示(二进制补码,一个补码或符号幅度),它们的结果都是明确定义的,但在后两种情况下,如果实现处理“负零”,则结果可能是陷阱表示。表示为陷阱。就个人而言,我几乎总是使用带有位运算符的无符号表达式,因此结果在值而不是表示方面100%定义良好。
最后,请注意,所写的答案可能仅适用于C. C和C ++是非常不同的语言,虽然我不太了解C ++,但据我所知,它可能在某些方面与C ... / p>
答案 1 :(得分:10)
<<
具有未定义的行为; >>
给出了实现定义的结果; &
,|
和^
运算符的结果是根据值的按位表示来定义的。 C中负数的表示允许三种可能性:二的补码,一个补码和符号幅度。当这些运算符用于负值时,实现使用的方法将确定数值结果。请注意,符号位为1且所有值位为零(对于二进制补码和符号幅度),或符号位和所有值位1(对于一些补码)的值明确允许为陷阱表示,在这种情况下,如果您使用生成此类值的运算符的参数,则行为未定义。
答案 2 :(得分:4)
位内容将相同,但结果值仍将依赖于实现。
使用按位运算时,您确实不应该将值看作有符号或无符号值,因为它在不同的级别上工作。
使用无符号类型可以避免一些麻烦。
答案 3 :(得分:2)
C89标准根据位位置定义了左移有符号数的行为。如果有符号类型或无符号类型都没有填充位,则无符号类型所需的行为,以及正有符号类型与无符号类型共享相同表示的要求,将意味着符号位紧靠最高有效值位的左侧
这在C89中,-1&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt; 39; t有填充位。如果存在没有填充比特的任何符号幅度实现,则-1&lt;&lt; 1将等于2。
C99标准将负值的左移改变为未定义行为,但基本原理中没有任何内容可以提供任何关于为什么(甚至根本没有提到变化)的线索。在某些实现实现中,C89所需的行为可能不太理想,因此允许这些实现自由选择更好的东西是有意义的。我没有看到任何证据表明标准的作者并不打算质量的补充实施应该继续提供C89规定的相同行为,但不幸的是他们并没有这样做。实际上是这么说的。