2015-09-23 2 views
10

std::exp Mit e^-infinity kehrt -infinity bei der Verwendung der Schwimmer Darstellung der Unendlichkeit und den Aufbau eines x64 binary mit Visual C++ 2013 ich es erwarten würde, zu berechnen, return 0, was passiert mit Win32-Builds, oder die Version std::exp, die eine double dauert.std :: exp des Schwimmers negativ Unendlich kehrt negative Unendlichkeit für x64 in Visual C baut ++ 2013

Der folgende Code, der als x64 erstellt wird, veranschaulicht das Problem.

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

Befehlszeilenoptionen für Kompilierung (von Visual Studio genommen):

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

Ausgabe von oben:

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

Warum passiert das das?

+2

Dies ist ein Fehler; Es ist in den Visual C++ 2015-Laufzeitbibliotheken behoben. –

+0

@JamesMcNellis - ist das nicht die definitive Antwort? –

Antwort

8

Ich würde normalerweise sagen, dass ein Fehler von einiger Beschreibung war, da C++ 11 aufschiebt für cmath Funktionalität C99 und C99 eindeutig in F.9.3.1 dass exp(−∞) returns +0. Beachten Sie jedoch, dass dies in einem Anhang der Norm steht:

Eine Implementierung, die __STDC_IEC_559__ definiert, muss den Spezifikationen in diesem Anhang entsprechen.

Das Makro erscheint nicht entweder 32- oder 64-Bit-Modus in MSVC in definiert werden, so dass es wahrscheinlich ist nicht ein Fehler und Sie können von Glück. Auch das Ändern des Gleitkomma-Modus zwischen /fp:strict und /fp:precise macht die Dinge nicht besser.

In allen Fällen scheint das Ergebnis zwischen 32-Bit- und 64-Bit-Ziel zu unterscheiden, und basierend auf dem Standard, der nur expcompute the base-e exponential of x mit scheinbar keine Anforderung angibt, wie es scheint, in Ordnung zu sein.


Wenn Sie nach einer schnellen Lösung sind, mit der pow Funktion die richtigen Ergebnisse zu erzeugen scheint:

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

Dies erzeugt Null für beide Linien unabhängig davon, ob Sie 64-bit/32-bit, debug/release oder fp:precise/fp:strict aber, ob das garantiert ist, konnte ich nicht sagen.

+1

Ist nicht der gesamte Anhang F optional? – hvd

+0

@hvd, hängt davon ab, ob MSVC '_ _STDC_IEC_559_ _' definiert. Ich habe es nicht lokal installiert und kann es nicht überprüfen. Ich werde die Antwort aktualisieren. – paxdiablo

+0

Ergebnis ++ Dies könnte in der Tat ein strenges/präzises Problem sein. – imallett

Verwandte Themen