Vin*_*ent 9 c++ standards integer ones-complement c++11
在一个补码架构上考虑以下代码:
int zero = 0;
int negzero = -0;
std::cout<<(negzero < zero)<<std::endl;
std::cout<<(negzero <= zero)<<std::endl;
std::cout<<(negzero == zero)<<std::endl;
std::cout<<(~negzero)<<(~zero)<<std::endl;
std::cout<<(1 << negzero)<<std::endl;
std::cout<<(1 >> negzero)<<std::endl;
Run Code Online (Sandbox Code Playgroud)
根据我对标准的解释:
\n\n\xc2\xa73.9.1/p3 基本类型 [basic.fundamental]中的 C++标准实际上将球扔到了 C 标准中:
\n\n\n\n\n有符号和无符号整数类型应满足 C 标准第 5.2.4.2.1 节中给出的约束。
\n
现在,如果我们转到 ISO/IEC 9899:2011 第 5.2.4.2.1 节,它给出了对\xc2\xa76.2.6.2/p2 整数类型的前向引用(重点是我的):
\n\n\n\n\n如果符号位为零,则不会影响结果值。如果符号位为 1,则应通过以下方式之一修改该值:
\n\n\n
\n\n- \n
符号位为 0 的相应值被取反(符号和大小);
- \n
符号位的值为 \xe2\x88\x92(2^M) (两个\xe2\x80\x99s 补码);
- \n
符号位的值为 \xe2\x88\x92(2^M \xe2\x88\x92 1) (ones\xe2\x80\x99 补码)。
其中哪一个适用是实现定义的,就像是符号位为 1 且所有值位为零的值(对于前两个),\n 还是符号位和所有值位为 1(对于 Ones\xe2\x80\x99补码),是一个陷阱表示或一个正常值。在符号和大小以及个位补数的情况下,如果此表示是正常值,则称为负零。
\n
因此,负零的存在是由实现定义的。
\n\n如果我们继续第 3 段:
\n\n\n\n\n如果实现支持负零,则只能通过以下方式生成它们:
\n\n\n
\n\n- \n
&、|、^、~、<< 和 >> 运算符以及产生此类值的操作数;
- \n
+、-、*、/ 和 % 运算符,其中一个操作数为负零\n且结果为零;
- \n
基于上述情况的复合赋值运算符。
未指定这些情况实际上是否生成负零或正常零,以及存储在对象中时负零是否变为正常零。
\n
因此,您显示的相关案例是否会生成负零尚未明确。
\n\n现在继续第 4 段:
\n\n\n\n\n如果实现不支持负零,则带有会产生此类值的操作数的 &、|、^、~、<< 和 >> 运算符的行为是未定义的。
\n
因此,相关操作是否会导致未定义的行为,取决于实现是否支持负零。
\n| 归档时间: |
|
| 查看次数: |
389 次 |
| 最近记录: |