Berechnungen führen zur falschen Bewertung der Existenz einer Lösung

waverider

Mitglied
Hallo an alle,
ich bin neu, studiere seit kurzem Informatik und habe ein Problem mit einer Aufgabe die wir lösen sollen.

Und ja, ich hab auch schon die sufu benutzt,
hab auch 2 ähnliche Threads gefunden, nur leider hat es mir nicht zu einer Lösung geholfen.
Vielleicht fehlt mir auch nur die richtige Vokabel um was passendes zu finden :/

Also folgendes:

Es geht im Prinzip um eine simple p-q berechnung.
Die Zahlen a, b und c sollen in der Form ax²+bx+c=0 eingegeben werden.

Weiterhin soll das Programm ausgeben ob es nur eine, zwei oder keine Lösungen gibt.
Daher überprüfe ich anschließend das Ergebniss nach der Form oben. Bei einfachen Werten funktioniert das auch perfekt.
Allerdings scheint die Prüfung bei folgenden Werten für a, b und c nicht zu funktionieren:
a=1, b=-4,2, c=4,21

Meine Vermutung ist ja, dass da schon intern irgendwo gerundet wird, und er daher bei der Prüfung nicht auf ==0 bzw !=0 kommt.

Kann mir jemand ein Tipp geben woran das liegt?
Achja, für Tips zum Programmierstil wäre ich auch dankbar :)


Und bitte nehmt mich nicht direkt auseinander,
studiere erst seit ein paar wochen ^^

[Java]
import java.util.Scanner;

public class Quadratic {

public static void main(String[] args) {

Scanner console = new Scanner(System.in);
double a, b, c;

System.out.println("Bitte geben sie Ihre Werte ein: ");
System.out.print("a = ");
a = console.nextDouble();
System.out.print("b = ");
b = console.nextDouble();
System.out.print("c = ");
c = console.nextDouble();

quadratic(a, b, c);

console.close();

}

public static void quadratic(double a, double b, double c) {
double x1=0, x2=0;

//Ist a != 0 ?
if (a!=0) {
x1 = ((-b+Math.sqrt((b*b-4*a*c)))/2*a); // Lösen nach p-q-Formel
System.out.println(x1); // <-- Später noch entfernen!!!
x2 = ((-b-Math.sqrt((b*b-4*a*c)))/2*a); // Lösen nach p-q-Formel
System.out.println(x2); // <-- Später noch entfernen!!!
//Zwei Lösungen
if (a*x1*x1+b*x1+c==0 && (a*x2*x2+b*x2+c==0) ) {
System.out.println("Erste Lösung = "+round1(x1));
System.out.println("Zweite Lösung = "+round1(x2));
}
else {
//Keine Lösung
if (a*x1*x1+b*x1+c!=0 && (a*x2*x2+b*x2+c!=0) ) {
System.out.println("Keine reele Lösung");
}
//Nur eine Lösung
else {
if (a*x1*x1+b*x1+c==0) {
System.out.println("Lösung: "+round1(x1));
}
else {
if (a*x2*x2+b*x2+c==0) {
System.out.println("Lösung: "+round1(x2));
}
}
}
}
}
else {
System.out.println("a muss ungleich 0 sein");
}
}

public static double round1(double value) {
if (Double.isNaN(value)) return value;
if (Double.isInfinite(value)) return value;
return Math.round(value * 10) / 10.0;
}

}

[/Java]

btw,
für den fall dass ich mich nicht eindeutig ausgedrückt habe,
hier nen bild von der aufgabenstellung:
http://www.abload.de/img/pqtnud0.jpg
 
Zuletzt bearbeitet:

Landei

Top Contributor
Das wichtigste zuerst: Wenn
Code:
b*b-4*a*c
negativ ist und du ziehst daraus die Wurzel, gibt es eine Exception. Du musst diesen Fall ("keine Lösungen") vor der Berechnung prüfen, damit es nicht dazu kommen kann.
 

waverider

Mitglied
guter tipp,
hab im code oben ne neue if-abfrage hinzugefügt

Java:
	public static void quadratic(double a, double b, double c) {
		double x1=0, x2=0;
		
		//Ist a != 0 ?
		if (a!=0)	{
			if (b*b-4*a*c<0)	{
				System.out.println("Keine reele Lösung");
			}
			else	{
				x1 = ((-b+Math.sqrt((b*b-4*a*c)))/2*a);					// Lösen nach p-q-Formel
				System.out.println(x1);									// <-- Später noch entfernen!!!
				x2 = ((-b-Math.sqrt((b*b-4*a*c)))/2*a);					// Lösen nach p-q-Formel
				System.out.println(x2);									// <-- Später noch entfernen!!!
				//Zwei Lösungen
				if (a*x1*x1+b*x1+c==0 && (a*x2*x2+b*x2+c==0) )	{
					System.out.println("Erste Lösung = "+round1(x1));
					System.out.println("Zweite Lösung = "+round1(x2));
				}
				else	{
					//Keine Lösung
					if (a*x1*x1+b*x1+c!=0 && (a*x2*x2+b*x2+c!=0) )	{
						System.out.println("Keine reele Lösung");
					}
					//Nur eine Lösung
					else	{					
						if (a*x1*x1+b*x1+c==0)	{
							System.out.println("Lösung: "+round1(x1));
						}
						else	{
							if (a*x2*x2+b*x2+c==0)	{
								System.out.println("Lösung: "+round1(x2));
							}
						}
					}
				}
			}
		}
		else	{
			System.out.println("a muss ungleich 0 sein");
		}																																				
	}
[/Java]

allerdings fange ich jetzt an mich zu fragen ob die werte auf dem aufgabenblatt falsch sind.
da ist z.B. für a=0,1 b=0,6 und c=0,9 eine Lösung von -3 angegeben... obwohl die wurzel ja negativ ist...
 

Deros

Bekanntes Mitglied
Allerdings scheint die Prüfung bei folgenden Werten für a, b und c nicht zu funktionieren:
a=1, b=-4,2, c=4,21

mit den Werten kommt halt tatsächlich x1 = 0.0 und x2 =-8.881784197001252E-16 raus und x2 ist dann halt nicht genau 0. Sprich du musst dein "ist gleich" etwas ungenauer definieren da beim Wurzeziehen es immer zu Rundungsfehlern kommen kann.
 

waverider

Mitglied
a=0,1 b=0,6 und c=0,9

für diese Werte habe ich jetzt mal den Prof angeschrieben,
mal sehen was er dazu sagt.

dennoch bekomme ich noch nicht die richtigen ergebnisse bei

a=1 b=-4,2 c=4,21
lösungen sollen 2,5 und 1,7 sein.

mein rechner hat das ausgerechnet
2.5472135954999584
1.652786404500042

gibt aber nur den ersten wert als richtig zurück.
ich nehme an, das da die prüfung nicht stimmt, weil intern gerundet wurde ?!
 

waverider

Mitglied
mit den Werten kommt halt tatsächlich x1 = 0.0 und x2 =-8.881784197001252E-16 raus und x2 ist dann halt nicht genau 0. Sprich du musst dein "ist gleich" etwas ungenauer definieren da beim Wurzeziehen es immer zu Rundungsfehlern kommen kann.

ok,
sowas dachte ich mir ja schon.

aber wie soll ich das denn ungenauer definieren?
dazu fällt mir nämlich nichts ein :/
 

Deros

Bekanntes Mitglied
auf jedenfall würde ich deine berechnung um auf 0 zu prüfen in eine variable auslagern, da du sie im zweifel jeweils 3 mal ausführst.

dann hast du 2 möglichkeiten, entweder du prüfst nicht ob a*x1*x1+b*x1+c!=0 sondern -0.0000001<a*x1*x1+b*x1+c<0.0000001 oder da du die Rechnung ja eh auslagern sollst machst du darauf nen cast nach int das sollte die Rundungsfehler auch eliminieren
 

homer65

Top Contributor
Mathematisch mußt du prüfen, ob der folgende Ausdruck
x = c/a - b*b/(4*a*a)
größer, kleiner oder gleich 0 ist.
Mit einem Computer und dem Datentyp double hast du Rundungsfehler.
Im Klartext heißt das, die Prüfung, ob x = 0 ist, funktioniert nicht.
Der Fall x=0 und damit eine Lösung ist so nicht feststellbar.
Immerhin kannst du bei X > 0 und x < 0 noch recht sicher sein.
 

Neue Themen


Oben