首先,你的第一个前提是错误的:
int negzero = -0;
应该在任何符合的架构上产生一个正常的零。
@101010 的回答中给出了相关参考:
3.9.1 基本类型 [basic.fundamental] §3:
... 有符号和无符号整数类型应满足 C 标准第 5.2.4.2.1 节中给出的约束。
稍后在 C 参考中:5.2.4.2.1 整数类型的大小
...前向引用:类型的表示(6.2.6)
和(仍然是 C): 6.2.6 类型的表示 / 6.2.6.2 整数类型 § 3
如果实现支持负零,它们只能通过以下方式生成:
所以negzero = -0
不是这样的构造,不应产生负 0。
对于以下几行,我将假设负 0 是在支持它的实现上以按位方式产生的。
C++ 标准根本不说负零,而 C 标准只是说它们的存在取决于实现。我找不到任何明确说明负零是否应该等于关系或相等运算符的正常零的段落。
所以我将在 C 参考文献中引用:6.5.8 关系运算符 §6
如果指定的关系为真,则每个运算符 <(小于)、>(大于)、<=(小于或等于)和 >=(大于或等于)应产生 1,如果是,则应产生 0 false.92) 结果的类型为 int。
并在 C++ 5.9 关系运算符 [expr.rel] §5
如果两个操作数(转换后)都是算术或枚举类型,则如果指定的关系为真,则每个运算符都应产生真,如果为假,则应产生假。
我对标准的解释是,实现可能允许整数值 0(负零)的替代表示,但它仍然是值 0 的表示,并且它应该在任何算术表达式中相应地执行,因为 C 6.2.6.2 整数类型§ 3 说:
负零 [...] 应仅由 [...] +、-、*、/ 和 % 运算符生成,其中一个参数为负零且结果为零
这意味着如果结果不为 0,则负 0 应该作为正常的 0 执行。
所以这两行至少是完美定义的,应该产生1
:
std::cout<<(1 << negzero)<<std::endl;
std::cout<<(1 >> negzero)<<std::endl;
这条线被明确定义为依赖于实现:
std::cout<<(~negzero)<<(~zero)<<std::endl;
因为一个实现可能有填充位。如果没有填充位,则在一个补码体系结构~zero
上是 negzero
,因此~negzero
应该产生 a0
但我无法在标准中找到负零是否应显示为0
或 as -0
。负浮点0 应该用减号显示,但对于整数负值似乎没有什么明确的。
对于涉及关系和相等运算符的最后 3 行,标准中没有任何明确的内容,所以我会说它是实现定义的
TL/DR:
依赖于实现:
std::cout<<(negzero < zero)<<std::endl;
std::cout<<(negzero <= zero)<<std::endl;
std::cout<<(negzero == zero)<<std::endl;
std::cout<<(~negzero)<<(~zero)<<std::endl;
完美定义,应产生 1:
std::cout<<(1 << negzero)<<std::endl;
std::cout<<(1 >> negzero)<<std::endl;