2015-09-23 111 views
10

使用std::exp來計算e^-infinity返回-infinity當使用浮點表示無窮大並使用Visual C++ 2013構建x64二進制文件時,我期望它返回0,這是Win32版本發生的情況,或std::exp的版本,其版本爲doublestd :: exp浮點負無窮在Visual C++ 2013中爲x64構建返回負無窮大

構建爲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 

爲什麼會出現這種情況?

+2

這是一個錯誤;它在Visual C++ 2015運行時庫中得到修復。 –

+0

@JamesMcNellis - 這不是最終的答案嗎? –

回答

8

我通常會說這是一些描述的bug,因爲C++ 11推遲到C99的cmath功能和C99明確指出在F.9.3.1exp(−∞) returns +0。但請記住,該標準的附錄中規定:

定義爲__STDC_IEC_559__的實現應符合本附件中的規範。

,宏觀不會出現在32位或64位模式MSVC這樣定義:它可能一個錯誤,你可能是出於運氣。在/fp:strict/fp:precise之間更改浮點模式也不會讓事情變得更好。

在所有情況下,結果似乎在32位和64位目標之間有所不同,並且基於僅標明expcompute the base-e exponential of x似乎沒有要求的標準,似乎沒有問題。


如果你是一個快速修復後,使用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-bit/32-bitdebug/releasefp:precise/fp:strict但是,這是否有保證,我不能說。

+1

附件F的整體是否可選? – hvd

+0

@hvd取決於MSVC是否定義了_ _STDC_IEC_559_ _。我沒有在本地安裝,因此無法檢查。我會更新答案。 – paxdiablo

+0

得分++這可能確實是一個嚴格/精確的問題。 – imallett