Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
Alprausch
Anmeldungsdatum: 24.10.2009 Beiträge: 47 Wohnort: Schweiz
|
Verfasst am: 27.02.2012, 22: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, 14: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, 23: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: 107
|
Verfasst am: 28.02.2012, 01: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, 09: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, 11: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, 11: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, 12: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, 13: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: 107
|
Verfasst am: 28.02.2012, 13:20 Titel: |
|
|
Variablen erst definieren, dann anlegen. |
|
Nach oben |
|
|
Alprausch
Anmeldungsdatum: 24.10.2009 Beiträge: 47 Wohnort: Schweiz
|
Verfasst am: 28.02.2012, 13: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, 14: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, 14: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: 107
|
Verfasst am: 28.02.2012, 15: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, 21: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: 4597 Wohnort: ~/
|
Verfasst am: 28.02.2012, 21: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, 21: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: 4597 Wohnort: ~/
|
Verfasst am: 28.02.2012, 22: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, 22: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 |
|
|
|