| 
				
					|  | Das deutsche QBasic- und FreeBASIC-Forum Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
 
 |  
 
	
		| Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |  
		| Autor | Nachricht |  
		| Proggy 
 
 
 Anmeldungsdatum: 01.04.2012
 Beiträge: 2
 
 
 | 
			
				|  Verfasst am: 01.04.2012, 03:08    Titel: Problem mit Ausgabe der Lösung (Quadr. Funktion) |   |  
				| 
 |  
				| 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 }
   
 Aber Bsp. bei x^2 -4x + 4 = 0 erfolgt richtig L = { 4 }
  . 
 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 |  |  
		|  |  
		| nemored 
 
  
 Anmeldungsdatum: 22.02.2007
 Beiträge: 4710
 Wohnort: ~/
 
 | 
			
				|  Verfasst am: 01.04.2012, 11:23    Titel: |   |  
				| 
 |  
				| 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 |  |  
		|  |  
		| MisterD 
 
  
 Anmeldungsdatum: 10.09.2004
 Beiträge: 3071
 Wohnort: bei Darmstadt
 
 | 
			
				|  Verfasst am: 01.04.2012, 11:27    Titel: |   |  
				| 
 |  
				| 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 |  |  
		|  |  
		| Proggy 
 
 
 Anmeldungsdatum: 01.04.2012
 Beiträge: 2
 
 
 | 
			
				|  Verfasst am: 01.04.2012, 15:13    Titel: |   |  
				| 
 |  
				| 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
  . 
 
  	  | 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 |  |  
		|  |  
		| nemored 
 
  
 Anmeldungsdatum: 22.02.2007
 Beiträge: 4710
 Wohnort: ~/
 
 | 
			
				|  Verfasst am: 02.04.2012, 00:14    Titel: |   |  
				| 
 |  
				|  	  | 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 |  |  
		|  |  
		|  |  
  
	| 
 
 | 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.
 
 |  |