9

-Ofast在我的程序中使用 gcc 选项会导致延迟要求。我写了简单的测试程序:

#include <iostream>
#include <math.h>

static double quiet_NaN = std::numeric_limits<double>::quiet_NaN();

int main()
{
    double newValue = 130000; 
    double curValue = quiet_NaN; 
    printf("newValue = %f\n", newValue); 
    printf("curValue = %f\n", curValue); 
    printf("isnan(newValue) = %d\n", isnan(newValue)); 
    printf("isnan(curValue) = %d\n", isnan(curValue)); 
    printf("newValue == curValue %d\n", (newValue == curValue)); 
    printf("newValue != curValue %d\n", (newValue != curValue)); 
}

我尝试使用默认标志和 -Ofast 运行它:

$ g++ TestPointer.cpp 
$./a.out 
newValue = 130000.000000
curValue = nan
isnan(newValue) = 0
isnan(curValue) = 1
newValue == curValue 0
newValue != curValue 1

$ g++ -Ofast TestPointer.cpp 
$ ./a.out 
newValue = 130000.000000
curValue = nan
isnan(newValue) = 0
isnan(curValue) = 1
newValue == curValue 1
newValue != curValue 0

所以结果!=并不==能被信任。这是否意味着我应该==!=仅当两个值都不是 nan 时,否则我应该在isnan之前进行测试?

是否保证isnan可以正常工作-Ofast?double with 的正确性==!=工作方式如何-Ofast?有人可以提供由添加的限制的完整列表-Ofast吗?

4

1 回答 1

12

您正在观察-ffast-math.

文档

-Ofast

无视严格的标准合规性。-Ofast 启用所有 -O3 优化。它还支持并非对所有符合标准的程序都有效的优化。它打开 -ffast-math 以及 Fortran 特定的 -fno-protect-parens 和 -fstack-arrays。

-ffast-数学

设置 -fno-math-errno、-funsafe-math-optimizations、-fno-trapping-math、-ffinite-math-only、-fno-rounding-math、-fno-signaling-nans 和 fcx-limited-range。

-仅有限数学

允许对假设参数和结果不是 NaN 或 +-Infs 的浮点算术进行优化。

对于这个标记为无效的,有几个 gcc 错误报告。

-ffast-math 和 isnan 的问题

此外,严格的 IEEE 浮点数的比较总是会导致错误。

在 C++ 中检查双精度(或浮点数)是否为 NaN

这不一定适用,-ffast-math但它解释了你展示的内容。

gcc 没有描述-ffast-math浮点如何工作的正式标准,因此如果您必须且不假设 gcc 版本之间的一致性,您只需凭经验计算出细节。更好的是,完全避免 和 的NaN组合-ffast-math

于 2014-12-05T12:39:27.040 回答