[c++] Rechenfehler in P-Q-Formel mit Funktionsaufruf

.::ASDF::.

Freizeitschrauber(in)
Hallo Zusammen,

bei meinem Programm rechnet die Funktion "Diskriminante" falsch. Wenn die Rechnung direkt in der "main" steht kommt das richtige raus.
Zum Beispiel für a=1, b=2, c=3 sollte das Ergebnis für die Diskriminante "-8" sein, es wird aber "+4" ausgegeben und bricht nicht bei der if-Bedingung (diskr < 0) ab.
Was habe ich falsch gemacht?


#include <iostream>
#include <cmath>
using namespace std;
double diskriminante();

double a=0, b=0, c=0;

double diskriminante()
{
double diskr;
diskr = pow(b,2)-4*a*c;
return diskr;
}

int main(){
double ergebnis2, ergebnis1, diskr, c, z;

cout <<"Quadratische Gleichung:\n" << endl;
cout <<"a = ? ";
cin >> a;
if (a == 0)
cout << "Keine Loesung (Divison durch Null)" << endl;
else {
cout <<"b = ? ";
cin >> b;
cout <<"c = ? ";
cin >> c;
diskr = diskriminante();

//diskr = pow(b,2)-4*a*c;
if (diskr < 0.0)
cout << "Keine reelen Loesungen" << endl;
else {
ergebnis1 = 1/(2*a)*(-b+sqrt(diskr));
ergebnis2 = 1/(2*a)*(-b-sqrt(diskr));

cout <<"\nLoesung:\n";
cout << "x1 = " << ergebnis1 << endl;
cout << "x2 = " << ergebnis2 << endl;
}
}
//Zur Kontrolle
z= diskriminante();
cout << z<<" z"<< endl;
cout <<diskr<<" diskr"<< endl;
cout <<diskriminante()<< " funk"<<endl;
return 0;
}




 
Erstmal würde ich empfehlen, die Funktion diskriminante so umzugestalten, dass sie die Parameter a,b,c erwartet, also:

double diskriminante(double a, double b, double c) {
return pow(b, 2) - 4 * a * c;
}

Werte in globalen Variablen zu übergeben kann zudem bei komplexeren Programmen zu Inkonsistenzen führen, am besten gar nicht erst angewöhnen. Und vielleicht solltest du auch überprüfen ob c == 0 ist.
 
Das Einzige, was mir einfiele, wäre:

diskr = pow(b,2)-4*a*c;

in

diskr = pow(b,2)-4.0*a*c;

zu ändern. Aber normal müsste die Überladung eines Int in Float / Double funktionieren. Der Rest sieht in Ordnung aus.
Ich hab aber keinen Compiler zur Hand, um es zu überprüfen.
 
Du hast c einmal global und einmal lokal in der main()-Funktion.

Nutze keine globalen Variablen zur Parameterübergabe, sondern stattdessen Call-by-Value oder Call-by-Reference. In dem Fall reicht ersteres, du kannst aber auch Call-by-Reference benutzen, das sollte in dem Fall keinen Unterschied machen.

Du brauchst übrigens in der Diskriminanten-Funktion keine Variablen zu definieren, du kannst auch direkt return pow(b, 2) - 4 * a * c schreiben.
 
Danke für eure Hilfe :daumen:. Jetzt rechnet die Funktion so wie sie soll. Die Globalen Variablen habe ich auch entfernt.

#include <iostream>
#include <cmath>
using namespace std;
double diskriminante();
double diskriminante(double a, double b, double c)
{
//double diskr;
//diskr = pow(b,2)-4*a*c;
return pow(b,2)-4*a*c;
}
int main(){
double ergebnis2, ergebnis1, diskr, ergebnis, tmp, a=0, b=0, c=0;

cout <<"Quadratische Gleichung:\n" << endl;
cout <<"a = ? ";
cin >> a;
cout <<"b = ? ";
cin >> b;
cout <<"c = ? ";
cin >> c;
diskr = diskriminante(a,b,c);
if (a==0) {
tmp = 0 -c;
ergebnis = tmp/b;
cout << "x= " << ergebnis << endl;
}
else {
if (diskr < 0.0)
cout << "Keine reelen Loesungen" << endl;
else {
ergebnis1 = 1/(2*a)*(-b+sqrt(diskr));
ergebnis2 = 1/(2*a)*(-b-sqrt(diskr));

cout <<"\nLoesung:\n";
cout << "x1 = " << ergebnis1 << endl;
cout << "x2 = " << ergebnis2 << endl;
}
}
return 0;
}
 
Woran lag es denn jetzt?

Es sah ja so aus, als ob 4 * a * c zum Zeitpunkt des Funktionsaufrufs == 0 war.

Dann wären aber auch die globalen a, b, c mit den richtigen Werten vorhanden gewesen...
(Der Stil mit den globalen Variablen war natürlich nicht sauber.)
 
Es fehlte für die Funktion die Parameterübergabe "double diskriminante(double a, double b, double c)" und bei "return" musste anstatt der Variable "diskr" die Berechnung hin "pow(b,2)-4*a*c".
Mit den globalen Variablen ging es auch, aber die sollte man ja vermeiden.
 
Ja das wäre sauber gewesen, aber ohne Parameterübergabe sollte die Funktion doch die globalen Variablen benutzen.

Wenn +4 herauskommt, wäre anzunehmen, dass pow(b,2) (b war mit 2 eingegeben) richtig funktioniert hat und 4*a*c falsch gerechnet worden wäre.

Und ob ich erst diskr = ... und dann return diskr mache, sollte auch unerheblich sein.

Ohne Trace kommt man aber wohl nicht dahinter ;) .
 
Hab es mal ausprobiert, geht auch so wie du es beschrieben hast.

Mein Hauptfehler war, dass ich "c" in der main nochmal als Kontrollvariable deklariert habe, obwohl die eigentlich bestandteil der Rechnung ist.
Damit kann die Funktion nur mit Parameterübergabe funktionieren.
 
Zurück