Java gibt NaN aus, obwohl Lösung -3 ist



  • Hallo,

    das Programm, um das es sich handelt soll drei Werte (a, b und c) einer quadratischen Gleichung in der Main-Methode einlesen und an die Methode, die hier zu sehen ist übergeben.

    Die Methode hier soll unterscheiden, ob es keine reelle Lösung gibt, eine eindeutige Lösung oder mehrere Lösungen. Zudem soll es noch eine Exception ausgeben, damit man nicht durch 0 teilt. Soweit so gut, das klappt im Prinzip auch alles, nur bei einer Eingabekombination gibt er mir ein NaN aus, obwohl -3 richtig ist. Ich komme nicht dahinter was dahinter steckt und wie ich das lösen kann. Wenn am Ende ein kleiner Rundungsfehler rauskommt und dann am Ende -2.999999999 steht ist mir egal. Nur das NaN soll da weg. 😞

    Folgende Eingaben habe ich gemacht und es kommt was richtiges raus:

    a = 1
    b = -12
    c = 35 ----> Zwei Lösungen: 7.0 und 5.0

    a = 0.2
    b = -0.8
    c = 0.8 ----> Lösung: 2.0

    a = 1
    b = 12
    c = 37 ----> Keine reelle Lösung

    a = 0
    b = 4
    c = 7 ----> a muss ungleich 0 sein

    Und jetzt die Eingabekombination, die mich zu einem Fehler führt:

    a = 0.1
    b = 0.6
    c = 0.9 ----> Die eindeutige Lösung ist -3, doch ich bekomme nur ein NaN ausgegeben.

    Ich wäre froh, wenn mir hier jemand helfen könnte.

    import java.util.*;
    
    public class quadGleichung
    {   public static void main(String[] args)
        {   Scanner console = new Scanner(System.in);
    
            double a, b, c, x1, x2;
    
            System.out.println("Bitte geben Sie a, b und c fuer: axx + bx + c = 0 ein\n");
    
            System.out.print("a = ");
            a = console.nextDouble();       
            System.out.print("b = ");
            b = console.nextDouble();
            System.out.print("c = ");
            c = console.nextDouble();
    
            String s = quadratic(a,b,c);
    
            System.out.println(s);
    
        }
    
        public static String quadratic(double a, double b, double c)
        {   double x1, x2; 
            double diskriminante = (b*b - 4*a*c) / (2*a);
            double runden = Math.pow(10, 10);
    
            if(a == 0)
            {   return "a muss ungleich 0 sein";
            }
    
            if(Math.round(diskriminante*runden)/runden == 0)
            {   x1 = (-b + Math.sqrt(b*b - 4*a*c)) / (2*a);
                return ("Loesung: " + x1);
            }
    
            if(Math.round(diskriminante*runden)/runden > 0)
            {   x1 = (-b + Math.sqrt(b*b - 4*a*c)) / (2*a);
                x2 = (-b - Math.sqrt(b*b - 4*a*c)) / (2*a);
                return ("Erste Loesung = " + x1 + "\nZweite Loesung = " + x2);
            }
    
            if(Math.round(diskriminante*runden)/runden < 0)
            {   return "Keine reelle Loesung";
            }
    
            return "pseudo";
        }
    }
    

  • Mod

    if(Math.round(diskriminante*runden)/runden == 0)
            {   x1 = (-b + Math.sqrt(b*b - 4*a*c)) / (2*a);
                return ("Loesung: " + x1);
            }
    

    In der if-Abfrage scheinst Du irgendwie die Diskriminante auf 0 zu runden, falls sie nahezu 0 ist. Dadrunter rechnest Du sie aber wieder neu aus, bzw. so etwas ähnliches. Bei Deinem Beispiel ist die Diskriminante mathematisch gesehen 0. Wenn Du das aber im Rechner rechnest, dann musst Du damit rechnen, dass es durch die interne Zahlendarstellung zu kleinen Abweichungen davon kommt. In diesem Fall sollte man davon ausgehen, dass Deine Diskriminante in Wirklichkeit minimal negativ ist. Und dann ziehst Du die Wurzel aus einer negativen Zahl und das ergibt nunmal NaN.

    Lösung: Wenn Du schon auf 0 rundest, dann setze dieses Wissen in die Formel dadrunter ein und lass die Wurzel ganz weg.


Anmelden zum Antworten