C++ DBL_MAX加法是如何工作的?

C++ DBL_MAX加法是如何工作的?,c++,c,double,C++,C,Double,代码 我无法理解为什么这两种功能的工作方式不同。这里发生了什么? 在C++和C标准中,整数版本和浮点版本可能会调用未定义的行为,因为计算结果x+y不能表示为执行算术的类型。†因此这两个函数都可能产生或甚至执行任何操作 然而,许多现实世界的平台为浮点运算提供了额外的保证,并以某种方式实现整数,让我们能够解释得到的结果 考虑到f,我们注意到许多流行的平台实现了IEEE 754中描述的浮点数学。按照该标准的规则,我们得到了LHS: 0 1 及 RHS产量 INF - DBL_MAX = INF.

代码


我无法理解为什么这两种功能的工作方式不同。这里发生了什么? 在C++和C标准中,整数版本和浮点版本可能会调用未定义的行为,因为计算结果
x+y
不能表示为执行算术的类型。†因此这两个函数都可能产生或甚至执行任何操作

然而,许多现实世界的平台为浮点运算提供了额外的保证,并以某种方式实现整数,让我们能够解释得到的结果

考虑到
f
,我们注意到许多流行的平台实现了IEEE 754中描述的浮点数学。按照该标准的规则,我们得到了LHS:

0
1

RHS产量

INF - DBL_MAX = INF.

因此,LHS!=RHS

转到
ff
:许多平台在两个补码中执行有符号整数计算。两个补码的加法是关联的,所以只要优化器不将其更改为与两个补码规则相矛盾的内容,比较就会产生true

后者是完全可能的(例如,请参阅),因此您不能依赖有符号整数溢出来完成我上面解释的工作。然而,在这种情况下似乎“很好”


†请注意,这不适用于无符号整数算术。在C++中,无符号整数实现算术模<代码> 2 ^ NUBATS/<代码>,其中代码> NUBATS< /CUD>是类型的位数。在这个算法中,每个整数都可以通过在
[0,2^NumBits-1]
中选取其等价类的代表来表示。所以这个算法永远不会溢出

对于那些怀疑浮点情况是否存在的人,UB:N4140 5/4[expr]说

如果在表达式求值期间,结果未在数学上定义或不在 对于其类型的可表示值,行为未定义


事实就是这样。INF和NANS是允许的,但在C++和C浮点数学中不需要。仅当有问题的浮点类型的
std::numeric_limits::is_iec559
为true时,才需要此选项。(或在C中,如果它定义了
\uuuuu STDC\uu IEC\uu559\uuuu
。否则,附录F的内容不需要适用。)如果任何一个IEC指标保证了我们IEEE的语义,行为定义得很好,可以执行我上面描述的操作。

两个函数都会导致未定义的行为。@2501但为什么未定义的行为?有符号变量的溢出是UB。您的添加超出了数值限制:您所做的是未定义的行为。double和long的二进制编码是不同的,因此这里有不同的结果被认为是“正常的”,但同样,您的代码是未定义的行为,应该被视为unpredictable@utkarsh13如果您将最大可能的数字和最大可能的nummer相加,您会期望结果是什么?当然,浮点运算不是未定义的行为吗?处理无穷大和NaN值在浮点类型中定义得很好,不是吗?@pmdj,例如允许
-ffast math
<代码> INF和<代码>楠<代码>来自IEEE浮点,而不是允许的但不需要它们的标准C++。@ UHHHHOMADBODIONS SUPACHOLD“定义STDCL IECIE555的实现应符合本附件中的规范”。如果没有,就不需要遵循IEEE。(我希望n1256是一个合理的文档,只是通过谷歌搜索发现。)@EOF“if
double
可以表示无穷大”,如果我们没有
\uu STDC\u IEC\u 559\uu
@nwellnhof这些引号在这里不适用,因为操作符
+
不是
中的函数。还要注意的是,如果定义了
\uu STDC\u IEC\u 559\uu
,则
巨大值等(在
函数中溢出时返回)只需要扩展到某个无穷大。一般来说,它们展开了一些正常量表达式。(参见N1256中的7.12/2,再次注意,Anex F仅适用于定义上述宏的情况。)
DBL_MAX + DBL_MAX = INF
INF - DBL_MAX = INF.
DBL_MAX - DBL_MAX = 0
DBL_MAX + 0 = DBL_MAX