gpt4 book ai didi

c - clang 和 gcc 之间的 float 操作结果不一致

转载 作者:太空宇宙 更新时间:2023-11-04 05:18:12 24 4
gpt4 key购买 nike

在 OSX 10.10 和 ubuntu 14.04 上分别编译和运行。

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

void testAtan() {
float temp1 = 62981764.0000000000000000f;
float temp2 = (2.14859168E8f * atanf(temp1));
printf("temp2: %.16f\n", temp2);
}

int main() {
printf("FLT_EVAL_METHOD=%d\n", FLT_EVAL_METHOD);
testAtan();
return 0;
}

在 OS X 上,它打印

FLT_EVAL_METHOD=0
temp2: 337499968.0000000000000000

在 ubuntu 上,它打印

FLT_EVAL_METHOD=0
temp2: 337500000.0000000000000000

有什么想法可以证明这一点以及使结果一致的方法吗?

最佳答案

您正在调用一个库函数 atanf,IEEE 754 标准不要求它必须如此精确地实现,以至于它会为所有实现产生相同的结果。

大多数实现的精度都在 0.5 ULP 以上,但这仍然足以让难以舍入的结果(实际结果接近两个 float 之间的中点的结果)有所不同。例如,如果实际结果是 f2 方向上的 float f1 的 0.4 ULP,则一个实现可以返回 f1,另一个返回 f2,它们仍然可以精确到 0.6 ULP(这很好,但并不罕见)。

如果您希望在任何地方都获得相同的结果,您应该合并您自己的 atanf 实现,它仅由基本的 IEEE 754 操作组成。然后它将在所有为基本操作提供 IEEE 754 语义的编译平台(即大多数编译平台)上产生相同的结果。这就是 Java 为使浮点初等函数结果可重现所做的:它在 the “netlib” implementation 上标准化。 .如果您设法在您希望定位的其他平台上编译它,您可以使用 Apple implementation Stephen Canon 指出:与 OS X 数学库中的许多其他函数一样,它提供了出色的标准合规性,并在准确性和速度之间取得了很好的平衡。

您还必须有可能使用任何“正确舍入”的数学库,然后结果将与任何其他正确舍入的数学库相同,因为对于初等函数的任何应用只有一个正确舍入的结果任何论点。一个正确舍入的库是 CRlibm ,但要点是您可以使用任何其他一个并获得与 CRlibm 相同的结果。 CRlibm 只提供 double 函数,但如果任何单精度标准函数的任何参数在直接正确舍入为单精度而不是正确舍入为 double 然后舍入为单精度时产生不同的结果,我会感到非常惊讶-精度。

编辑:

在将大参数传递给单精度反正切函数的特殊情况下,实现可能会自愿选择一个结果而不是它计算出的最精确结果还有一个原因:实现可能认为最好有函数总是返回 -π/2 和 π/2 之间的结果。对于非常大的参数,实际结果接近 π/2,而最接近 π/2 的单精度浮点近似值恰好在 π/2 以上。在这些情况下,atanf 的一些实现选择返回恰好低于 π/2 的 float ,而其他实现可以选择返回恰好高于(和最接近)π/2 的 float 。我在 blog post 中讨论过这个(但对我的意见持保留态度:我不怎么使用 float ,所以我的意见不重要)。博客文章是在 double 的上下文中构建的,但实际上,在 double 中,我们很幸运(对于函数 atan 的特殊情况):最近的 double π/2 的近似值恰好低于它,因此实际上不需要选择。

关于c - clang 和 gcc 之间的 float 操作结果不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26497891/

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