在Visual C 2013中,x64版本的浮动负无穷大的std :: exp返回负无穷大

前端之家收集整理的这篇文章主要介绍了在Visual C 2013中,x64版本的浮动负无穷大的std :: exp返回负无穷大前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
使用std :: exp来计算e ^ -infinity返回-infinity,当使用无穷大的浮点数表示,并使用Visual C 2013构建一个x64二进制文件.我希望它返回0,这是Win32构建或版本的std :: exp需要一个double.

下面的代码,构建为x64,演示了这个问题.

#include <limits>
#include <iostream>

int main(const int argc,const char** argv) {
    std::cout << "exp of float -infinity: " << std::exp(-std::numeric_limits<float>::infinity()) << std::endl;
    std::cout << "exp of double -infinity: " << std::exp(-std::numeric_limits<double>::infinity()) << std::endl;
}

用于编译的命令行选项(取自Visual Studio):

/GS /Wall /Gy /Zc:wchar_t /Zi /Gm- /Od /sdl /Fd"x64\Release\vc120.pdb" /fp:precise /D "_MBCS" /errorReport:prompt /WX /Zc:forScope /Gd /Oi /MD /Fa"x64\Release\" /EHsc /nologo /Fo"x64\Release\" /Fp"x64\Release\NumericLimitsTest.pch"

产量以上:

exp of float -infinity: -1.#INF
exp of double -infinity: 0

为什么会发生这种情况?

解决方法

我通常会说这是一个描述的错误,因为C11对于cmath功能而言是C99,而C99在F.9.3.1中明确指出exp(-∞)返回0.然而,请记住,在附件标准规定:

An implementation that defines __STDC_IEC_559__ shall conform to the specifications in this annex.

在MSVC中,32位或64位模式似乎并未定义该宏,因此它可能不是错误,您可能会失去运气. / fp:strict和/ fp:精准之间也不会改变浮点模式,使事情变得更好.

在所有情况下,结果似乎在32位和64位目标之间有所不同,并且基于标准,它只表示exp将计算x的base-e指数,似乎没有要求如何,似乎是可以的.

如果您在快速修复后,使用pow函数似乎可以生成正确的结果:

#define DBL_E 2.71828182845904523536
#define FLT_E 2.71828182845904523536f
std::cout
    << "exp of float -infinity: "
    << std::pow(FLT_E,-std::numeric_limits<float>::infinity())
    << std::endl;
std::cout
    << "exp of double -infinity: "
    << std::pow(DBL_E,-std::numeric_limits<double>::infinity())
    << std::endl;

无论您是否拥有64位/ 32位,调试/释放或fp:精确/ fp:strict,这两个行都会生成零,但是无论是否保证,我都不能说.

猜你在找的C&C++相关文章