gpt4 book ai didi

c++ - DBL_MAX 加法是如何工作的?

转载 作者:搜寻专家 更新时间:2023-10-31 00:56:45 32 4
gpt4 key购买 nike

代码

#include<stdio.h>
#include<limits.h>
#include<float.h>

int f( double x, double y, double z){
return (x+y)+z == x+(y+z);
}

int ff( long long x, long long y, long long z){
return (x+y)+z == x+(y+z);
}

int main()
{
printf("%d\n",f(DBL_MAX,DBL_MAX,-DBL_MAX));
printf("%d\n",ff(LLONG_MAX,LLONG_MAX,-LLONG_MAX));
return 0;
}

输出

0
1

我无法理解为什么这两个函数的工作方式不同。这里发生了什么?

最佳答案

在 C++ 和 C 标准看来,整数版本和浮点版本可能会调用未定义行为,因为计算结果 x + y在执行算术的类型中不可表示。因此这两个函数都可能产生甚至做任何事情。

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

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

DBL_MAX + DBL_MAX = INF

INF - DBL_MAX = INF.

RHS yield

DBL_MAX - DBL_MAX = 0

DBL_MAX + 0 = DBL_MAX

因此 LHS != RHS。

继续 ff :许多平台以二进制补码执行有符号整数计算。二进制补码的加法是关联的,因此只要优化器不将其更改为与二进制补码规则相矛盾的内容,比较结果就会为真。

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


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

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

If during the evaluation of an expression, the result is not mathematically defined or not in the range ofrepresentable values for its type, the behavior is undefined.

是这样的。 inf 和 NaN 是允许的,但在 C++ 和 C float 学中不是必需的。仅当 std::numeric_limits::is_iec559<T> 时才需要对于所讨论的浮点类型是正确的。 (或者在 C 中,如果它定义了 __STDC_IEC_559__ 。否则,不需要应用附件 F 的内容。)如果 iec 指示符中的任何一个保证我们的 IEEE 语义,则行为被明确定义为执行我上面描述的操作。

关于c++ - DBL_MAX 加法是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38826007/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com