| Vorheriges Thema anzeigen :: Nächstes Thema anzeigen | 
	
	
		| Autor | Nachricht | 
	
		| Alprausch 
 
  
 Anmeldungsdatum: 24.10.2009
 Beiträge: 47
 Wohnort: Schweiz
 
 | 
			
				|  Verfasst am: 27.02.2012, 21:57    Titel: Gleitkommazahlen und ihre Genauigkeit + Variablentypen |   |  
				| 
 |  
				| Hallo Leute 
 Ich hab mich heute wieder ein wenig mit QBasic beschäftigt und dabei ein kleines Beispielprogramm zu Variablentypen aus dem Grossen QBasic Buch abgetippt.
 
 
  	  | Code: |  	  | ' Beispielprogramm für Variablen 
 CLS
 Artikel$ = "Die Programmierer-Fibel"                       'String
 Anzahl% = 5                                                'Integer
 Preis = 49.8                                               'Single
 Gesamt# = Anzahl% * Preis
 PRINT "Artikel: "; Artikel$
 PRINT Anzahl%; "Stück auf Lager"
 PRINT Preis; "DM pro Stück"
 PRINT "Gesamtwert:"; Gesamt#
 
 | 
 
 Wenn ich dieses Programm aber nun ausführe bekomme ich ein völlig falsches Resultat. Es müsste ganz genau 249 geben. Bei mir kommt aber 248.9999irgendwas raus.
 
 Dies ist auf diesem Bild sehr schön zu erkennen.
 
   
 Von den Variablen her sollte ja so eigentlich alles stimmen. Was mich nur verwirrt ist dass in dem Beispiel für die Variable Gesamt ein DOUBLE benutzt wird. Es ist mir aber auch klar dass es für das Resultat mindestens 2 Stellen benötigt.
 
 Wenn ich der Variable Preis noch ein ! anhänge (was ja nicht nötig wäre) um sie als SINGLE zu definieren ist der Preis nacher 0.
 
 Oben ist der ganze Code und ich finde den Fehler einfach nicht. Habt Ihr vielleicht eine Idee wo der Fehler sein könnte?
 
 Wie gesagt. Der Code ist 1 zu 1 aus dem Buch abgetippt. Habe es mehrfach kontrolliert und keine Tippfehler gefunden.
 
 Zwar habe ich die Funktionsweise der Variablen mal grundsätzlich verstanden, jedoch möchte ich dieses Programm dennoch richtig zum laufen bringen.
 
 Ich hoffe jemand kann mir einen Tipp geben. Muss ja nicht gleich die Lösung sein. Dann kann ich selbst noch ein wenig studieren. Brauche aber den nötigen Wink mit dem Zaunpfahl
   
 Also denn... Noch einen schönen Abend.
 
 mfg Alprausch
 
 Zuletzt bearbeitet von Alprausch am 28.02.2012, 13:01, insgesamt 2-mal bearbeitet
 |  | 
	
		| Nach oben |  | 
	
		|  | 
	
		| Jojo alter Rang
 
  
 Anmeldungsdatum: 12.02.2005
 Beiträge: 9736
 Wohnort: Neben der Festplatte
 
 | 
			
				|  Verfasst am: 27.02.2012, 22:22    Titel: |   |  
				| 
 |  
				| Gleitkommazahlen sind nicht präzise. Wenn du genaue Ergebnisse benötigst, musst du mit fixem Komma arbeiten, wofür Qb von Haus aus keinen Datentyp bietet, aber man kann das emulieren, indem man z.B. alle Beträge mit 100 multipliziert. _________________
 » Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
 
  |  | 
	
		| Nach oben |  | 
	
		|  | 
	
		| HorstD 
 
 
 Anmeldungsdatum: 01.11.2007
 Beiträge: 110
 
 
 | 
			
				|  Verfasst am: 28.02.2012, 00:41    Titel: |   |  
				| 
 |  
				| Versuch's mal damit: 
 
  	  | Code: |  	  | CLS Artikel$ = "Die Programmierer-Fibel"                       'String
 Anzahl% = 5                                                'Integer
 Preis = 49.8                                               'Single
 Gesamt# = Anzahl% * Preis
 PRINT "Artikel: "; Artikel$
 PRINT Anzahl%; "Stück auf Lager"
 PRINT Preis; "DM pro Stück"
 PRINT " Gesamtwert: ";
 PRINT USING "###.##"; gesamt#
 | 
 |  | 
	
		| Nach oben |  | 
	
		|  | 
	
		| Alprausch 
 
  
 Anmeldungsdatum: 24.10.2009
 Beiträge: 47
 Wohnort: Schweiz
 
 | 
			
				|  Verfasst am: 28.02.2012, 08:14    Titel: |   |  
				| 
 |  
				| Vielen Dank für den Tipp! 
 Funktioniert einwandfrei.
 
 Aber was macht dieser Befehl genau?
 
 mfg Alprausch
 |  | 
	
		| Nach oben |  | 
	
		|  | 
	
		| Jojo alter Rang
 
  
 Anmeldungsdatum: 12.02.2005
 Beiträge: 9736
 Wohnort: Neben der Festplatte
 
 | 
			
				|  Verfasst am: 28.02.2012, 10:37    Titel: |   |  
				| 
 |  
				| Naaaaaaaaaaain! Die Veränderung von HorstD kaschiert die falsche Rechnung nur, indem Nachkommastellen bei der Ausgabe auf dem Bildschirm abgeschnitten werden. Das interne Ergebnis ist immer noch nicht korrekt! Verwende niemals Gleitkommazahlen (Single / Double), wo du exakte Ergebnisse benötigst, also ganz besonders niemals bei Geldrechnungen! Nimm lieber alle Beträge mal hundert und teile sie bei der Ausgabe auf dem Bildschirm durch hundert. _________________
 » Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
 
  |  | 
	
		| Nach oben |  | 
	
		|  | 
	
		| Alprausch 
 
  
 Anmeldungsdatum: 24.10.2009
 Beiträge: 47
 Wohnort: Schweiz
 
 | 
			
				|  Verfasst am: 28.02.2012, 10:52    Titel: |   |  
				| 
 |  
				| Ok. Wusste ich ja nicht. 
 Hab es jetzt mal so umgeschrieben wie du es mir empfohlen hast.
 Kommt aber das selbe dabei heraus.
 
 
  	  | Code: |  	  | ' Beispielprogramm für Variablen 
 CLS
 Artikel$ = "Die Programmierer-Fibel"                     'String
 Anzahl% = 5                                              'Integer
 Preis = 49.8                                             'Single
 Gesamt# = (Anzahl% * Preis) * 100
 PRINT "Artikel: "; Artikel$
 PRINT Anzahl%; "Stück auf Lager"
 PRINT Preis; "DM pro Stück"
 PRINT "Gesamtwert: "; Gesamt# / 100
 | 
 
 PS: Ich hab das Thema mal umbenannt weil ich noch mehr Fragen zu QBasic habe. Versuche es aber erst selbst zu lösen. Bin grad mit den Variablentypen am experimentieren.
 
 mfg
 |  | 
	
		| Nach oben |  | 
	
		|  | 
	
		| Alprausch 
 
  
 Anmeldungsdatum: 24.10.2009
 Beiträge: 47
 Wohnort: Schweiz
 
 | 
			
				|  Verfasst am: 28.02.2012, 11:49    Titel: |   |  
				| 
 |  
				| Das Problem konnte ich selbst lösen. 
 Musste nur bei der Variable "Gesamt" den Datentyp entfernen und schon ging es.
 
 Hab ewig probiert und versucht. Aber jetzt geht es
   
 
  	  | Code: |  	  | ' Beispielprogramm für Variablen 
 CLS
 Artikel$ = "Die Programmierer-Fibel"                    'String
 Anzahl% = 5                                             'Integer
 Preis = 49.8                                            'Single
 Gesamt = (Anzahl% * Preis) * 100                        'Eingaben * 100
 PRINT "Artikel: "; Artikel$
 PRINT Anzahl%; "Stück auf Lager"
 PRINT Preis; "DM pro Stück"
 PRINT "Gesamtwert: "; Gesamt / 100                      'Resultat / 100
 
 
 
 | 
 
 
 Nun aber folgendes Problem. Habe ja noch erwähnt dass ich mit den Variablen am herumspielen bin.
 
 Folgendes kleines Programm habe ich dazu geschrieben.
 
 
  	  | Code: |  	  | ' Mehreren Variablen den Typen zuordnen 
 CLS
 
 ' Variablen anlegen
 Auto = 123
 Baum = 456
 Crono = 789
 Diesel = 123
 Esel = 456
 Fisch = 789
 
 'Variablen definieren
 DEFINT A-C              ' Variable A-C als Integer definieren
 DEFSTR D-F              ' Variable D-F als String definieren
 
 'Variablen ausgeben
 PRINT Auto
 PRINT Baum
 PRINT Crono
 PRINT Diesel
 PRINT Esel
 PRINT Fisch
 | 
 
 Wenn ich dieses Programm aber nun ausführe bekomme ich nur drei 0 angezeigt.
 
 Eigentlich hätte ich mir da was anderes gewünscht. Werde aber weiter daran arbeiten und den Fehler suchen und versuchen zu beheben.
 
 Bin aber froh wenn Ihr mir Tipps geben könnt
   
 mfg
 |  | 
	
		| Nach oben |  | 
	
		|  | 
	
		| Sebastian Administrator
 
  
 Anmeldungsdatum: 10.09.2004
 Beiträge: 5969
 Wohnort: Deutschland
 
 | 
			
				|  Verfasst am: 28.02.2012, 12:15    Titel: |   |  
				| 
 |  
				| Hallo! 
 
  	  | Zitat: |  	  | Wenn ich dieses Programm aber nun ausführe bekomme ich nur drei 0 angezeigt. | 
 Den DEFxxx Befehl setzt man üblicherweise ganz an den Anfang des Programms. Er gilt für die Variablen, die du danach deklarierst.
 
 Das heißt für dein Programmbeispiel, wenn du am Anfang des Programms schreibst
 
 so wird diese Variable implizit als SINGLE-Gleitkommazahl deklariert (--> entspricht Auto!).
 Anschließend legst du dann mit DEFINT fest, dass Variablen mit A implizit als INTEGER angelegt/verwendet werden sollen.
 Wenn du daraufhin dann die Variable Auto ausliest, wird QB schauen, ob es eine Integer-Variable namens Auto kennt. Da du am Anfang nur eine SINGLE-Variable namens Auto angelegt hast, ist der Integer Auto undefiniert und folglich 0.
 
 In QB ist nämlich auch Folgendes hier möglich:
 
  	  | Code: |  	  | CLS 
 Auto = 123
 Auto% = 456
 Auto$ = "Hallo"
 
 PRINT Auto
 PRINT Auto%
 PRINT Auto$
 
 SLEEP
 | 
 Führt zur Bildschirmausgabe:
 
 Man erhält nicht etwa eine "Duplicated definition" Fehlermeldung, sondern kann durchaus mehrere Variablen mit gleichem Bezeichner, aber unterschiedlichem Datentyp gleichzeitig haben. Das ist zwar überhaupt kein guter Programmierstil, aber QB lässt es zu.
 
 Zu deinem Gleitkommazahl-Problem am Anfang: Ich schließe mich da Jojos Empfehlung völlig an. Verwende lieber Ganzzahlen (idealerweise LONG) und rechne dann intern mit Cent-Beträgen statt mit Euro. So sparst du dir den Nachkommaanteil bei den Rechnungen und vermeidest die Genauigkeitsprobleme bei Gleitkommazahlen.
 
 Wenn du QB 7.1 (QBX) verwendest, gäbe es auch noch eine andere Möglichkeit. QB 7.1 bietet extra für Rechnungen mit Geldbeträgen einen eigenen Festkommazahl-Datentyp namens CURRENCY an. Er ist zwar beim Wertebereich nicht so flexibel wie die Gleitkommadatentypen, aber dafür genau.
 
  	  | Code: |  	  | CLS 
 DIM Preis AS CURRENCY
 DIM Anzahl AS INTEGER
 DIM Gesamt AS CURRENCY
 
 Preis = 49.8
 Anzahl = 25
 
 PRINT "Einzelpreis: "; Preis
 PRINT "Anzahl: "; Anzahl
 
 Gesamt = Preis * Anzahl
 
 PRINT "Gesamtpreis: "; Gesamt
 
 SLEEP
 | 
 Ausgabe:
 
 
   
 Hier die Hilfe-Beschreibungen zum Datentyp (inkl. Angabe des Wertebereichs):
 
 
   
 
   
 Übrigens: Fang bitte für jedes unterschiedliche Thema ein eigenes Topic an. Wenn du einen Sammelthread für alle unterschiedlichen Fragen anlegst, findet man nachher nichts mehr wieder. Daher bitte für jedes unterschiedliche Thema ein eigenes Forenthema anlegen (natürlich mit treffendem Themen-Titel).
 
 Viele Grüße!
 Sebastian
 _________________
 
   Die gefährlichsten Familienclans | Opas Leistung muss sich wieder lohnen - für 6 bis 10 Generationen!
 |  | 
	
		| Nach oben |  | 
	
		|  | 
	
		| HorstD 
 
 
 Anmeldungsdatum: 01.11.2007
 Beiträge: 110
 
 
 | 
			
				|  Verfasst am: 28.02.2012, 12:20    Titel: |   |  
				| 
 |  
				| Variablen erst definieren, dann anlegen. |  | 
	
		| Nach oben |  | 
	
		|  | 
	
		| Alprausch 
 
  
 Anmeldungsdatum: 24.10.2009
 Beiträge: 47
 Wohnort: Schweiz
 
 | 
			
				|  Verfasst am: 28.02.2012, 12:34    Titel: |   |  
				| 
 |  
				| Ok. Das werde ich gleich mal ausprobieren. Vielen Dank. 
 Wenn ich aber für jedes meine Probleme einen Thread anlege wird es ne Menge geben
   
 Darum dachte ich sei für meine Fragen die ich sosnt nicht lösen kann ein Sammelthread genau das richtige.
 
 Edit:
 Habe jetzt mal das Programm mit den Variablen so umgebaut dass die Zuweisung als erstes kommt und dann das Anlegen.
 
 Jetzt bekomme ich aber beim Ausführen eine Fehlermeldung.
 
 Diesel soll ein falscher Datentyp sein.
 
 
  	  | Code: |  	  | ' Das grosse QBasic Buch - Stefan Dittrich - 2. Auflage - Seite 73 
 ' Mehreren Variablen den Typen zuordnen
 
 CLS
 
 'Variablen definieren
 DEFINT A-C              ' Variable A-C als Integer definieren
 DEFSTR D-F              ' Variable D-F als String definieren
 
 ' Variablen anlegen
 Auto = 123
 Baum = 456
 Crono = 789
 Diesel = ABCD
 Esel = EFGH
 Fisch = IJKL
 
 'Variablen ausgeben
 PRINT Auto
 PRINT Baum
 PRINT Crono
 PRINT Diesel
 PRINT Esel
 PRINT Fisch
 
 SLEEP
 | 
 
 mfg
 |  | 
	
		| Nach oben |  | 
	
		|  | 
	
		| MisterD 
 
  
 Anmeldungsdatum: 10.09.2004
 Beiträge: 3071
 Wohnort: bei Darmstadt
 
 | 
			
				|  Verfasst am: 28.02.2012, 13:18    Titel: |   |  
				| 
 |  
				| Diesel = ABCD sorgt dafür dass das programm nach einer variable ABCD sucht, und weil irgendwer beim entwurf von basic mal dachte, sowas wäre cool (so eine dumme idee...), erzeugt er kommentarlos dann ne integer-variable ABCD mit wert 0, du kannst aber der Stringvariable Diesel nicht ne Zahl zuweisen => falscher datentyp. Du musst Diesel = "ABCD" schreiben wenn das ein string sein soll, damit der computer das unterscheiden kann. _________________
 "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 |  | 
	
		|  | 
	
		| Alprausch 
 
  
 Anmeldungsdatum: 24.10.2009
 Beiträge: 47
 Wohnort: Schweiz
 
 | 
			
				|  Verfasst am: 28.02.2012, 13:31    Titel: |   |  
				| 
 |  
				| Es funktioniert. Vielen Dank. 
 Hab es jetzt so gemacht.
 
 
  	  | Code: |  	  | ' Das grosse QBasic Buch - Stefan Dittrich - 2. Auflage - Seite 73 
 ' Mehreren Variablen den Typen zuordnen
 
 CLS
 
 'Variablen definieren
 DEFINT A-C              ' Variable A-C als Integer definieren
 DEFSTR D-F              ' Variable D-F als String definieren
 
 ' Variablen anlegen
 Auto = 123
 Baum = 456
 Crono = 789
 Diesel = "ABCD"
 Esel = "1234"
 Fisch = "IJKL"
 
 'Variablen ausgeben
 PRINT Auto
 PRINT Baum
 PRINT Crono
 PRINT Diesel
 PRINT Esel
 PRINT Fisch
 
 SLEEP
 | 
 
 Nun kommt mir aber noch eine Frage dazu in den Sinn.
 
 In Variable Esel habe ich jetzt testweise eine Zahl eingegeben. Kann ich diese Zahl zum rechnen verwenden oder geht das nicht?
 
 Was mich auch noch stört ist dass ich bei den Stringvariablen alles in "" setzen muss. Am Beispiel Esel (Dummer Name...) wäre es ja eine Zahl. Diese könnte man genau so gut als Integer verwenden. Dies geht dann aber nicht weil der Inhalt der Variable in "" steht. Kann man das irgendwie umgehen?
 
 mfg
 |  | 
	
		| Nach oben |  | 
	
		|  | 
	
		| Sebastian Administrator
 
  
 Anmeldungsdatum: 10.09.2004
 Beiträge: 5969
 Wohnort: Deutschland
 
 |  | 
	
		| Nach oben |  | 
	
		|  | 
	
		| HorstD 
 
 
 Anmeldungsdatum: 01.11.2007
 Beiträge: 110
 
 
 | 
			
				|  Verfasst am: 28.02.2012, 14:29    Titel: |   |  
				| 
 |  
				|  	  | Zitat: |  	  | Dies geht dann aber nicht weil der Inhalt der Variable in "" steht. Kann man das irgendwie umgehen? | 
 
 Wenn du mit Zahlen in Strings rechnen willst, sieh' dir den Befehl VAL an.
 (Oder die Zahen gleich als integer definieren).
 |  | 
	
		| Nach oben |  | 
	
		|  | 
	
		| Alprausch 
 
  
 Anmeldungsdatum: 24.10.2009
 Beiträge: 47
 Wohnort: Schweiz
 
 | 
			
				|  Verfasst am: 28.02.2012, 20:09    Titel: |   |  
				| 
 |  
				| Ich glaube ich habe die Funktion jetzt endlich richtig verstanden. Diese dient wahrscheinlich nicht dazu Strings zu definieren. 
 Diese Funktion wird eher gerechnet sein um nur mit Zahlen zu arbeiten wenn eine Zahl in eine Variable geschrieben wird und ich dann diese Variable definieren kann wie ich es benötige.
 
 Hab ich das richtig verstanden?
 
 Hab mir jetzt das Beispiel so zurecht gelegt:
 
 
  	  | Code: |  	  | ' Das grosse QBasic Buch - Stefan Dittrich - 2. Auflage - Seite 73 
 ' Mehreren Variablen den Typen zuordnen
 
 CLS
 
 'Variablen definieren
 DEFINT A-C              ' Variable A-C als Integer definieren
 DEFSNG D-F              ' Variable D-F als String definieren
 
 ' Variablen anlegen
 Auto = 123.25
 Baum = 456.25
 Crono = 789.25
 Diesel = 123.25
 Esel = 456.25
 Fisch = 789.25
 
 'Variablen ausgeben
 PRINT Auto
 PRINT Baum
 PRINT Crono
 PRINT Diesel
 PRINT Esel
 PRINT Fisch
 
 SLEEP
 | 
 
 mfg
 |  | 
	
		| Nach oben |  | 
	
		|  | 
	
		| nemored 
 
  
 Anmeldungsdatum: 22.02.2007
 Beiträge: 4710
 Wohnort: ~/
 
 | 
			
				|  Verfasst am: 28.02.2012, 20:36    Titel: |   |  
				| 
 |  
				|  	  | Alprausch hat Folgendes geschrieben: |  	  | Ich glaube ich habe die Funktion jetzt endlich richtig verstanden. Diese dient wahrscheinlich nicht dazu Strings zu definieren. 
 | 
 Welche Funktion meinst du?
 
 Normalerweise definierst du eine Variable eines bestimmten Datentyps mit DIM. QBASIC macht das aber so, dass es immer, wenn es eine nicht definierte Variable entdeckt, diese in einem speziellen Standarddatentyp definiert (SINGLE oder DOUBLE, weiß nicht mehr so genau). DEFINT legt jetzt allerdings fest, dass dieser Standarddatentyp eben nicht mehr SINGLE (oder so) ist, sondern INTEGER. Wegen DEFINT A-C bezieht sich das nur auf Variablen, die mit den Buchstaben A, B oder C beginnen.
 
 Angelegt wird die Variable allerdings erst an der Stelle
 
 Jetzt verfügt das Programm über eine neue INTEGER-Variable namens Auto und mit dem Wert 123.
 _________________
 Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1.
 |  | 
	
		| Nach oben |  | 
	
		|  | 
	
		| Alprausch 
 
  
 Anmeldungsdatum: 24.10.2009
 Beiträge: 47
 Wohnort: Schweiz
 
 | 
			
				|  Verfasst am: 28.02.2012, 20:50    Titel: |   |  
				| 
 |  
				| Ich meinte die DEF...-Funktion 
 Wie Sie funktioniert und für was man die Funktion gebrauchen sollte.
 
 Das habe ich jetzt glaube ich verstanden. Habe manchmal halt länger als andere...
   
 mfg
 |  | 
	
		| Nach oben |  | 
	
		|  | 
	
		| nemored 
 
  
 Anmeldungsdatum: 22.02.2007
 Beiträge: 4710
 Wohnort: ~/
 
 | 
			
				|  Verfasst am: 28.02.2012, 21:24    Titel: |   |  
				| 
 |  
				|  	  | Alprausch hat Folgendes geschrieben: |  	  | und für was man die Funktion gebrauchen sollte | 
 Wenn du das so schreibst - am besten gar nicht
  . Besser (weil weniger fehleranfällig) ist es, alle Variablen explizit mit DIM zu deklarieren. 
 (Übrigens ist das keine Funktion, sondern eine Anweisung; Funktionen haben Rückgabewerte.)
 _________________
 Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1.
 |  | 
	
		| Nach oben |  | 
	
		|  | 
	
		| Alprausch 
 
  
 Anmeldungsdatum: 24.10.2009
 Beiträge: 47
 Wohnort: Schweiz
 
 | 
			
				|  Verfasst am: 28.02.2012, 21:33    Titel: |   |  
				| 
 |  
				| Es wurde ja im Buch auch nur als Möglichkeit genannt. 
 Ich denke nicht dass ich es jemals brauchen werde.
 
 Kann die Variablen ja auch mit den Kurzzeichen $ ! # % & den jeweiligen Typ zuweisen.
 
 mfg
 |  | 
	
		| Nach oben |  | 
	
		|  | 
	
		|  |