MSVC 中的 std::isfinite

11
C++11和C11标准定义了std::isfinite函数。Visual Studio 2012似乎没有将其作为cmathmath.h的一部分提供,但有amp_math.h似乎提供此函数isfinite是否可与std::isfinite互换使用?文档没有讨论调用NAN时的行为,并且我没有VS编译器来测试这一点。
2个回答

18
作为Marius已经指出的,amp_math.h中的isfinite应该在C++ AMP中使用,这是一种类似于CUDA或OpenCL的用于许多核架构上的并行计算的MS扩展。由于此函数只能在实际的AMP受限函数(通常是GPU内核)中使用,因此对于您来说它不会有太多的通用性。

很遗憾,VS 2012不支持C++11的数学和浮点控制函数。但是,一旦您确定您在使用VC并为其实现了特殊代码,您就可以使用<float.h>中的_finite(或者更好的是!_finite),这是一个自VS 2003以来就得到支持的MS特定函数。但请记住,_finite只接受double,因此会将任何非double参数转换(尽管VC似乎没有适当的long double),带来所有相关的影响(虽然INF和静默的NaN应该可以无问题地转换,但我不确定在转换中对信号NaN进行陷阱处理是否也会导致对std::finite的直接调用产生结果)。

VC 的标准库有 其他类似函数 来适应它们缺乏 C++11/C99 支持的情况(例如 _isnan 等)。 (为什么他们拒绝只删除那些函数前面的下划线并在 _controlfp 周围放置一个简单的 <cfenv> 包装器,从而更接近完整的 C++11 支持,这是一个完全不同的问题。)

编辑:除此之外,检查 INFNaN 的直接方法也可能有效:

template<typename T> bool isfinite(T arg)
{
    return arg == arg && 
           arg != std::numeric_limits<T>::infinity() &&
           arg != -std::numeric_limits<T>::infinity();
}

当然,这也意味着可能会陷入信号传递NaN的同样问题(尽管我必须承认我对信号传递NaN和浮点异常的复杂性不是很熟悉)。


2
好了,这已经够让我头痛的了,为什么不直接使用http://www.boost.org/doc/libs/1_52_0/libs/math/doc/sf_and_dist/html/math_toolkit/utils/fpclass.html呢? - pmr
或许这是不言而喻的,但你在编辑中的isfinite函数非常特定于C++。 - pattivacek
@patrickvacek 确实如此,但是 Visual Studio 对 C 的支持也不够好。我看到答案只回答了问题中的 C++ 部分,但是 OP 似乎知道这两种语言,因此如果需要,应该能够推断出答案的 C 版本。 - Christian Rau

5

amp_math.h 中的 isfinite 只能从标记为 restrict(amp) 的函数中调用,即使行为相同,也不能互换。


1
您的回答很到位,但是Christian Rau对可能性的阐述使其成为更好的答案。我的问题没有表述清楚,不是您的回答的问题。 - pmr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接