浮点负无穷大的std :: exp在Visual C ++ 2013中为x64生成返回负无穷大

时间:2015-09-23 05:56:57

标签: c++ visual-c++

使用std::exp计算e^-infinity时使用infinity的float表示并使用Visual C ++ 2013构建x64二进制文件时返回-infinity。我希望它返回0,这是什么适用于Win32版本或版本为std::exp的{​​{1}}。

以下代码(构建为x64)演示了此问题。

double

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

#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;
}

以上输出:

/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" 

为什么会这样?

1 个答案:

答案 0 :(得分:8)

我通常会说这是一些描述的错误,因为C ++ 11推迟使用C99实现cmath功能,而C99在F.9.3.1明确指出exp(−∞) returns +0。但是,请记住标准附件中的内容:

  

定义__STDC_IEC_559__的实现应符合本附件中的规范。

该宏似乎没有在MSVC中以32位或64位模式定义,因此它可能一个错误,你可能会失去运气。在/fp:strict/fp:precise之间更改浮点模式也不会让事情变得更好。

在所有情况下,结果似乎在32位和64位目标之间有所不同,并且基于仅表明exp compute the base-e exponential of xpow似乎没有要求如何的标准,它似乎还可以。

如果您在快速修复后,使用#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-bit/32-bit

无论您是debug/releasefp:precise/fp:strict还是$attach = $mail.Attachments.Add($attachment) $attach.PropertyAccessor.SetProperty("http://schemas.microsoft.com/mapi/proptag/0x3712001F", "Volume.png") ,这都会为这两行生成零,但无论是否有保证,我都无法说出。< / p>