quadratische gleichungen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
senseye
User
Beiträge: 15
Registriert: Sonntag 12. September 2021, 23:00

Hallo,

ich habe eine Programmieraufgabe bekommen in der ich quadratische Gleichungen lösen soll, es funktioniert auch alles.

Aufgabe:
Das Programm soll eine quadratische Gleichung der Form
ax**2+bx+c=0 lösen können. Der Nutzer gibt hierfür die
Zahlen a, b, c ein. Das Programm prüft die Diskriminante, also
b**2−4ac , ob diese positiv, null oder negativ ist und gibt dann
aus wie viele Lösungen es gibt und ggf. deren Werte.

Verwendet habe ich folgende Formel aus meinem Tafelwerk:
https://www.file-upload.net/download-14 ... 2.jpg.html

Mein Programm:

Code: Alles auswählen

import math

a = float(input("a: "))
b = float(input("b: "))
c = float(input("c: "))

diskriminante = b**2 - 4 * a * c

if diskriminante < 0:
    print("Keine Lösung")
elif diskriminante == 0:
    x = -(b/(2*a)) + math.sqrt((b**2-4*a*c)/(4*a**2))
    print("x:", round(x, 3))
else:
    x1 = -(b/(2*a)) + math.sqrt((b**2-4*a*c)/(4*a**2))
    x2 = -(b/(2*a)) - math.sqrt((b**2-4*a*c)/(4*a**2))
    print("x1:", round(x1, 3))
    print("x2:", round(x2, 3))
Starte ich das Programm und übergebe follgende Zahlen:
a = 2
b = -16
c = 32
erhalte ich das Ergebnis 4, was richtig ist.

Trage ich aber an Stelle der Variablen die Werte in die Formel:

Code: Alles auswählen

-(-16/(2*2)) + math.sqrt((-16**2-4*2*32)/(4*2**2))
bekomme ich einen Fehler:

Code: Alles auswählen

ValueError: math domain error
Benutze ich meinen Taschenrechner mit der Formel und eingesetzten Werten, bekomme ich auch einen Fehler.

Mein Frage ist jetzt, warum funktioniert die Berechnung mit Variablen, aber nicht mit den eingegeben Werten?
Eigentlich müsste die Rechnung in beiden Fällen einen Fehler verursachen?

Zusammenfassung:

Code: Alles auswählen

a = 2
b = -16
c = 32
-(b/(2*a)) + math.sqrt((b**2-4*a*c)/(4*a**2))
funktioniert...

Code: Alles auswählen

-(-16/(2*2)) + math.sqrt((-16**2-4*2*32)/(4*2**2))
funktioniert nicht...

Ich hoffe mir kann jemand erklären, warum das mit Variablen funktioniert und mit eingesetzten Werten nicht?
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Weil du ein Operator-Präzedenz-Problem hast. b**2 quadriert die -16, womit eine positive Zahl resultiert.

-16**2 wird aber als -(16**2) ausgewertet, weil der **-Operator stärker bindet. Und negative reelle Zahlen haben keine Wurzel.
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@senseye: Anmerkungen zum Quelltext: Der Teilausdruck der Diskriminante kommt mehrfach im Code vor. Wenn man die schon mal ausgerechnet hat, kann man den Wert auch wiederverwenden, statt ihn noch mal neu zu berechnen.

Auch andere Teile der Rechnung stehen mehrfach im Code.

Gleitkommazahlen vergleicht man besser nicht mit ``==`` oder ``!=`` weil die nicht alle exakt gespeichert werden können. Das `math`-Modul hat eine Funktion dafür. Diesen Test muss man dann auch vorziehen, denn der „fast Null“-Wert kann auch negativ sein, und dann gibt es trotzdem eine Lösung.

Die Programmlogik und die Benutzerinteraktion trennt man normalerweise. Also Eingabe, Berechnung, und Ausgabe des Ergebnisses. Dann kann man die einzelnen Teile einzeln testen, einfacher in Funktionen auslagern, und ersetzen. Beispielsweise Ein- und Ausgabe über eine GUI statt über die Konsole.

`round()` verwendet man nur selten, wenn man tatsächlich mit dem gerundeten Wert weiterrechnen möchte. Stellenbegrenzung bei der Ausgabe wird üblicherweise über die Formatierung als Zeichenkette erledigt.

Ungetestet:

Code: Alles auswählen

#!/usr/bin/env python3
import math


def main():
    a, b, c = float(input(f"{variable_name}: ") for variable_name in "abc")

    diskriminante = b ** 2 - 4 * a * c
    is_not_zero = math.isclose(diskriminante, 0)
    if is_not_zero and diskriminante < 0:
        loesungen = []
    else:
        d = -(b / (2 * a))
        e = math.sqrt(diskriminante / (4 * a ** 2))
        loesungen = [d + e]
        if is_not_zero:
            loesungen.append(d - e)

    if not loesungen:
        print("Keine Lösung")
    else:
        for i, loesung in enumerate(loesungen, 1):
            print(f"x{i}: {loesung:.3f}")


if __name__ == "__main__":
    main()
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@__blackjack__: float kann man nicht auf einen Generator anwenden, da ist was mit den Klammern schief gelaufen.
is_not_zero funktioniert nicht. math.close hat standardmäßig einen Relativvergleich, der bei 0 immer fehlschlägt. Außerdem müßte es is_zero heißen.
Wenn diskriminante leicht negativ ist, kommst Du in den else-Zweig und bekommst dort den ValueError.

Code: Alles auswählen

#!/usr/bin/env python3
import math


def main():
    a, b, c = (float(input(f"{variable_name}: ")) for variable_name in "abc")

    diskriminante = b ** 2 - 4 * a * c
    is_zero = math.isclose(diskriminante, 0, abs_tol=1e-12)
    if not is_zero and diskriminante < 0:
        loesungen = []
    else:
        d = -(b / (2 * a))
        if is_zero:
            loesungen = [d]
        else:
            e = math.sqrt(diskriminante / (4 * a ** 2))
            loesungen = [d - e, d + e]

    if not loesungen:
        print("Keine Lösung")
    else:
        for i, loesung in enumerate(loesungen, 1):
            print(f"x{i}: {loesung:.3f}")

if __name__ == "__main__":
    main()
senseye
User
Beiträge: 15
Registriert: Sonntag 12. September 2021, 23:00

@__deets__

Deine Erklärung hat mein Problem gelöst.
Ich habe dann einfach (-16)**2 geschrieben und es hat funktioniert.
Danke O_o
Antworten