2015-06-09 4 views
8

Stattdessen gibt diese Operation -1.IND zurück, da sqrt(-1) -1.IND zurückgibt. Ist der Domänenfehler, der auf der C++ reference erwähnt wird, dass diese sqrt für negative Werte zurückgibt nicht die Information, dass dies tatsächlich ist i?Warum nicht pow (sqrt (-1), 2) -1 zurückgeben?

Gibt es eine Möglichkeit, diese Operation für alle negativen Zahlen durchzuführen, so dass sie den richtigen Wert zurückgibt, d. H. pow(sqrt(-36), 2) wird -36 zurückgeben?

+0

Per Definition ist eine gerade Potenz einer reellen Zahl positiv. – bereal

+8

Was Sie brauchen, ist eine komplexe Zahlenbibliothek. – Mysticial

+0

Wenn überhaupt, sollte es 0 auslassen oder zurückgeben (weil der reelle Teil 0 ist und 0^2 0 ist). –

Antwort

12

Sie können std::complex verwenden Ihr Ziel zu erreichen, wie folgt aus:

#include <complex> 
#include <iostream> 

int main() { 
    const std::complex<double> result = 
    std::pow(std::sqrt(std::complex<double>(-36,0)), 2); 
    std::cout << result << std::endl; 
    std::cout << "Real part = " << result.real() << std::endl; 
} 

Ausgang:

(-36,0) 
Real part = -36 

Beachten Sie, dass std::sqrt(std::complex) hier verwendet wird.


Der Grund für das Verhalten Sie ist die Unterschriften von sqrt begegnet, nämlich:

Doppel sqrt (double x);

float sqrt (float x);

lange doppelte sqrt (lange doppelte x);

Doppel-Quadrat (T x); // zusätzliche Überlastungen für integrale Typen

was bedeutet, dass unabhängig davon, welche Prototyp verwendet werden, Sie bekommen nichts besser als ein nan (oder a + inf), da die Rückgabetypen können nicht den imaginären Teil unterstützen . Deshalb existiert std::complex existiert.

Also, sqrt(-1) wird wahrscheinlich durch eine nan ersetzt werden, die nicht von pow() behandelt werden kann, so dass -1 wegen des Exponenten intakt bleibt. Als Ergebnis sind die Informationen bereits verloren, nachdem der Anruf an sqrt() und pow() nichts dagegen tun kann.

+0

Ich denke, cppreference hat eine bessere Beschreibung von [std :: sqrt] (http://en.cppreference.com/w/cpp/numeric/math/sqrt). –

+0

Ja @ShafikYaghmour, cppreference ist eine gute Alternative. – gsamaras

3

std::sqrt is defined, um implementierungsdefinierte Fehler bei einem Domänenfehler zurückzugeben. In diesem Fall ist (arg := -1) < -0 ein Domänenfehler.

std::pow is also defined, um einen von der Implementierung definierten Fehler bei einem Domänenfehler zurückzugeben.

So erhalten -1.Ind ist eine plausible Lösung.

Wie Mystical aufgezeigt hat, benötigen Sie eine komplexe Zahlenbibliothek.

6

Weil Sie die Funktion double sqrt(double) aufrufen, und der double Rückgabewert kann nur reelle Zahlen, unendlich (mit Vorzeichen) oder NaN speichern. Es gibt keine Vertretung für i.

Wenn Sie komplexe Zahlen speichern möchten, verwenden Sie std::complex.

4

Von this sqrt reference page:

Wenn das Argument kleiner als -0 ist, FE_INVALID angehoben und NaN zurückgegeben.

Und dann von this pow reference page

... wenn ein Argument NaN ist, wird NaN

zurück

So einfach Sie nicht pow(sqrt(x), y) für ein wirkliches x, die negativ ist verwenden können.

+0

Sehr nette Erklärung auch, Wunder, warum es 0 upvotes hat. Wird diese Änderung machen! – gsamaras

0

Wenn Sie C++ 14 verwenden, können Sie wörtliche Operatoren für komplexe verwenden: #include

<complex> 
#include <iostream> 

int 
main() 
{ 
    using namespace std::literals::complex_literals; 
    auto z = std::pow(std::sqrt(-36.0 + 0.0i), 2.0); 
    std::cout << z << '\n'; 
} 

Ausführen dieses erhalte ich:

[email protected]:~$ ./cpow 
(-36,4.40873e-15) 

Ich kenne den letzten gcc und clang Unterstützung dieses. Es sieht aus wie VS2015 tut auch.

Dies ist eigentlich ein Post-C++ 14-Zusatz, aber es ist immer noch in einem std Namensraum statt .