使用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指数,似乎没有要求如何,似乎是可以的.
#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,这两个行都会生成零,但是无论是否保证,我都不能说.