Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht Das deutsche QBasic- und FreeBASIC-Forum
Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
 
FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen  RegistrierenRegistrieren
ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin
Zur Begleitseite des Forums / Chat / Impressum
Aktueller Forenpartner:

Problem mit Ausgabe der Lösung (Quadr. Funktion)

 
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu QBasic.
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
Proggy



Anmeldungsdatum: 01.04.2012
Beiträge: 2

BeitragVerfasst am: 01.04.2012, 03:08    Titel: Problem mit Ausgabe der Lösung (Quadr. Funktion) Antworten mit Zitat

Guten Morgen,

ich lese hier schon ein paar Tage mit und habe mich die letzten Tage mal wieder mit Qbasic beschäftigt. Geschrieben habe ich u.a. ein Programm, um die Lösungen einer Quadratischen Funktion zu ermitteln, abhängig von Normalform oder Allgemeiner Form.

Soweit bin ich auch erstmal zufrieden mit dem Programm und es funzt. Nur habe ich bei einigen Fällen das Problem, daß es anstatt der einen Lösung, die es gibt, diese doppelt anzeigt.

Bsp. ist die Funktion x^2 - 7x + 12.25 = 0 gegeben. Einzigste Lösung ist hierbei 3.5.

Aber anstatt auszugeben: L = { 3.5 }
erfolgt die Ausgabe so hier: L = { 3.5 / 3.5 } verwundert

Aber Bsp. bei x^2 -4x + 4 = 0 erfolgt richtig L = { 4 } lächeln.

Mir geht hierbei nur um ästethische Probleme, da das Programm ja funktioniert. Anbei noch der Quellcode:

Code:
...
101 SUB Allgemein
102 DO
103 CLS
104 PRINT
105 PRINT "ax^2 + bx + c = 0"
106 PRINT "================="
107 PRINT
108 INPUT "a..."; a
109 INPUT "b..."; b
110 INPUT "c..."; c
111 IF a = 0 THEN
112 PRINT "a darf nicht 0 sein."
113 DO: LOOP WHILE INKEY$ = ""
114 GOTO 101
115 END IF
116 CLS
117 PRINT
118 PRINT a; "x^2 + ( "; b; ") x + ( "; c; ") = 0"
119 D = b ^ 2 - (4 * a * c)
120 LOCATE 4, 1
121 IF D < 0 THEN
122   PRINT "L = {/}"
123 ELSEIF D = 0 THEN
124   PRINT "L = {"; -b / (2 * a); "}"
125   ELSEIF D > 0 THEN
126   x1 = -b / (2 * a) - SQR(D)
127   x2 = -b / (2 * a) + SQR(D)
128   PRINT "L = { "; x1; "/"; x2; "}"
129   END IF
...
201 SUB Normalform
202 DO
203 CLS
204 PRINT
205 PRINT "x^2 * px + q = 0"
206 PRINT "================"
207 PRINT
208 INPUT "p..."; p
209 INPUT "q..."; q
210 CLS
211 PRINT
212 PRINT "x^2 + ( "; p; ") x + ( "; q; ") = 0"
213 D = p ^ 2 / 4 - q
214 LOCATE 4, 1
215 IF D < 0 THEN
216    PRINT "L = {/}"
217 ELSEIF D > 0 THEN
218    x1 = -(p / 2) - SQR(D)
219    x2 = -(p / 2) + SQR(D)
220    PRINT "L = { "; x1; "/"; x2; "}"
221 ELSEIF D = 0 THEN
222    PRINT "L = {"; -p / 2; "}"
223 END IF
...


Wäre wirklich dankbar für Hilfe.

Gruß
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
nemored



Anmeldungsdatum: 22.02.2007
Beiträge: 4594
Wohnort: ~/

BeitragVerfasst am: 01.04.2012, 11:23    Titel: Antworten mit Zitat

Nur mal so nebenbei: das Wort "einzigste" gibt es nicht ...

Ich vermute, das Problem liegt in der Abfrage D = 0. Beim Rechnen mit SINGLE- oder DOUBLE-Werten lassen sich gewisse Rechenungenauigkeiten nicht vermeiden. Möglicherweise kannst du das Problem so vermeiden:
Code:
215 IF ABS(D) < 0.0001 THEN
216    PRINT "L = {"; -p / 2; "}"
217 ELSEIF D < 0 THEN
218    PRINT "L = {}"
219 ELSEIF D > 0 THEN
220    x1 = -(p / 2) - SQR(D)
221    x2 = -(p / 2) + SQR(D)
222    PRINT "L = { "; x1; ";"; x2; "}"
223 END IF

(wobei in Zeile 219 ein ELSE reichen würde) Der Schwellwert .0001 ist willkürlich gewählt und kann an die eigenen Bedürfnisse angepasst werden; wenn er zu groß ist, wird auch leicht einmal eine existierende zweite Lösung unterschlagen.

Ich habe übrigens die Schreibweise der Lösungsmenge an den üblichen Standard angepasst; kannst du natürlich halten wie du willst.


edit: noch was - das GOTO 101 in Zeile 114 halte ich für keine gute Idee. Mal ganz abgesehen davon, dass sich das GOTO hier sehr leicht vermeiden lässt, springst du immer wieder vor die äüßere DO-Schleife. Aus Schleifen hinaus- oder in Schleifen hineinzuspringen sollte man aber möglichst vermeiden (abgesehen vom erlaubten Sprachkonstrukt EXIT). Wenn du schon springen willst, dann zumindest zur Zeile 103.
_________________
Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1.


Zuletzt bearbeitet von nemored am 01.04.2012, 11:32, insgesamt einmal bearbeitet
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
MisterD



Anmeldungsdatum: 10.09.2004
Beiträge: 3071
Wohnort: bei Darmstadt

BeitragVerfasst am: 01.04.2012, 11:27    Titel: Antworten mit Zitat

Das liegt an der eingeschränkten maschinengenauigkeit bei gleitkommazahlen (frag mal wikipedia dazu). Was du machen willst ist nicht "if D=0 then" prüfen sondern "if D < e" mit e=0.00001. Du darfst i.A. gleitkommazahlen niemals mit = vergleichen, denn da kommt fast immer mist raus.
_________________
"It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration."
Edsger W. Dijkstra
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Proggy



Anmeldungsdatum: 01.04.2012
Beiträge: 2

BeitragVerfasst am: 01.04.2012, 15:13    Titel: Antworten mit Zitat

Erstmal vielen Dank für die Antworten. Zumindest weiß ich nun, woran es liegt. Ich habe jetzt nicht vor noch extrem viel zu verändern daran.

MisterD hat Folgendes geschrieben:
Das liegt an der eingeschränkten maschinengenauigkeit bei gleitkommazahlen (frag mal wikipedia dazu). Was du machen willst ist nicht "if D=0 then" prüfen sondern "if D < e" mit e=0.00001


Gelesen hab ich schon dazu, und nun weiß ich auch wie es berechnet wird.

nemored hat Folgendes geschrieben:
edit: noch was - das GOTO 101 in Zeile 114 halte ich für keine gute Idee. Mal ganz abgesehen davon, dass sich das GOTO hier sehr leicht vermeiden lässt, springst du immer wieder vor die äüßere DO-Schleife. Aus Schleifen hinaus- oder in Schleifen hineinzuspringen sollte man aber möglichst vermeiden (abgesehen vom erlaubten Sprachkonstrukt EXIT). Wenn du schon springen willst, dann zumindest zur Zeile 103.

Hierzu noch ein paar Erläuterungen, wozu das dienen soll: Es soll nach jeder Aufgabe die Möglichkeit gegeben sein, in dem jeweiligen SUB (Allgemein oder Normalform) eine weitere Aufgabe zu rechnen - mit [w]. Oder aber bei [ESC] je nach Wahl a) Hauptprogramm oder b) kompletter Abbruch. Ist zwar noch nicht so ganz ausgereift, aber es ging mir vorrangig um Funktionalität (Nullstellen berechnen). Zumindest diese Auswahl zw. Hauptprogramm oder kompletten Abbruch muß ich noch einbauen.

Geht es hier "nur" um das GOTO 101 ?

Zitat:
Ich habe übrigens die Schreibweise der Lösungsmenge an den üblichen Standard angepasst; kannst du natürlich halten wie du willst.

Danke, aber ich laß das lieber so wie es ist. Leider gibt es kein "Leere Menge Zeichen", deshalb nur der Strich. Mir gefällt es so, wie es ist zwinkern.

Zitat:
(wobei in Zeile 219 ein ELSE reichen würde)

Wenn ich das jetzt richtig im Kopf habe, wollte er das nicht mitmachen, deshalb ELSEIF anstatt ELSE. Ich werde das gleich nochmal probieren.

edit 1: ELSE macht er nicht. Da kommt dann: "erwartet end of statement"

edit 2: Bei Eingabe von [w] springt das Programm an den Anfang vom Hauptmenü. Das ist soweit erstmal in Ordnung.

Gruß
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
nemored



Anmeldungsdatum: 22.02.2007
Beiträge: 4594
Wohnort: ~/

BeitragVerfasst am: 02.04.2012, 00:14    Titel: Antworten mit Zitat

Zitat:
edit 1: ELSE macht er nicht. Da kommt dann: "erwartet end of statement"

komisch ... meinst du wirklich nur ein "ELSE" und nicht etwa ein (falsches) "ELSE D > 0 THEN" oder etwas in der Art?

Zitat:
Geht es hier "nur" um das GOTO 101 ?

Es geht mir darum, dass du mit dem GOTO aus der Schleife heraus springst, obwohl das völlig unnötig ist; du kannst ja auch an den Anfang in der Schleife springen. Grundsätzlich würde ich versuchen, das GOTO komplett zu vermeiden, aber im Augenblick geht es mir speziell um den Sprung in die Zeile 101.

Zitat:
Leider gibt es kein "Leere Menge Zeichen",

Die Schreibweise { } IST eine von zwei möglichen Schreibweisen für die leere Menge.
_________________
Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu QBasic. Alle Zeiten sind GMT + 1 Stunde
Seite 1 von 1

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.

 Impressum :: Datenschutz