是否定义了有符号整数的按位运算的结果?
我知道>>
符号整数上的行为可以取决于实现(具体来说,左操作数是负数时)。
其他人呢: ~
, >>
, &
, ^
, |
? 当它们的操作数是内置types( short
, int
, long
, long long
)的有符号整数时,保证结果是相同的(就位内容而言),好像它们的types是无符号的?
对于负操作数, <<
具有未定义的行为,而>>
的结果是实现定义的(通常是“算术”右移)。 <<
和>>
在概念上不是按位运算符。 它们是算术运算符,相当于乘法或除法运算的两个适当的幂,这些运算符在其上定义明确。
至于真正的按位运算符^
, ~
, |
和&
,它们操作操作数(可能为提升)types的值的位表示。 对于每个可能的有符号表示forms(二进制补码,一个补码或符号大小),他们的结果都是明确定义的,但在后两种情况下,如果实现将“负零”代表作为陷阱。 就个人而言,我几乎总是使用带位运算符的无符号expression式,以便根据值而不是表示forms 100%地定义结果。
最后,请注意,这个答案写成可能只适用于C. C和C ++是非常不同的语言,虽然我不知道C ++,我知道它可能会有所不同,在一些这些领域从C …
- 负值的左移
<<
具有未定义的行为; - 负值的右移
>>
给出了实现定义的结果; -
&
,的结果 和^
运算符是根据值的按位表示来定义的。 C中负数的表示允许有三种可能:二进制补码,一个补码和符号幅度。 当这些运算符用于负值时,实现使用的方法将确定数字结果。
请注意,符号位1和所有值位为零(对于二进制补码和符号幅度)或符号位和所有值位1(对于补码)的值明确允许为陷阱表示 ,并且在此如果你使用这些运算符的参数来产生这样的值,那么行为是未定义的。
位的内容将是相同的,但结果值仍然是实现相关的。
在使用按位操作时,实际上不应该将值看作有符号或无符号值,因为这是在不同的级别上工作的。
使用无符号types可以使您免于某些麻烦。
C89标准定义了基于比特位置的左移符号数的行为。 如果无符号和无符号types都没有填充位,则无符号types所需的行为与正符号types与无符号types共享相同表示的要求将暗示符号位立即位于最高有效位的左侧。
在C89中,-1 << 1在没有填充位的二进制补码实现上是-2,而在没有填充位的补码实现上是-3。 如果没有填充位的符号量级实现,那么-1 << 1将等于2。
C99标准将负值的左移改为未定义行为,但理由中没有提供任何线索(甚至根本没有提到改变)。 C89所要求的行为在一些补充实现中可能不太理想,所以允许这些实现自由地select更好的东西是有意义的。 我没有看到任何证据表明标准的作者并不打算质量二补的实现应该继续提供C89所要求的相同的行为,但不幸的是他们实际上并没有这样说。