 |
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 |
goooofy
Anmeldungsdatum: 12.09.2005 Beiträge: 69
|
Verfasst am: 20.06.2010, 19:02 Titel: runden auf 6 Nachkommastellen |
|
|
Hallo,
ich möchte gerne einen DOUBLE auf 6 Nachkommastellen runden, erhalte aber oft Ergebnisse mit "0000001" oder "9999999" am Ende (siehe folgendes Beispiel). Wandel ich am Ende auf SINGLE, reicht die Genauigkeit leider nicht mehr (nur 3 Nachkommastellen). Das ist mir allerdings auch ein Rätsel, wird die Genauigkeit für Singels in der Datentypübersicht doch eigentlich mit 7 Stellen angegeben...
Code: | #include "vbcompat.bi"
DIM AS DOUBLE e
DIM AS STRING r1
e = 2001.12323*8.4322/2
PRINT "Ungerundet:";e
r1 = FORMAT$(e, "###0.000000")
MID(r1,INSTR(r1,","),1)= "."
e=VAL(r1)
PRINT "Gerundet auf 6 Nachkommastellen (FIX):";FIX(e * 1000000) / 1000000
PRINT "Gerundet auf 6 Nachkommastellen (FORMAT$):";e
PRINT "Ergebnis als SINGLE:"; CSNG(e)
SLEEP |
Kann mir vielleicht jamand zeigen, wie ich eine entsprechende Rundung hinbekomme?
Vielen Dank schonmal. |
|
Nach oben |
|
 |
28398
Anmeldungsdatum: 25.04.2008 Beiträge: 1917
|
|
Nach oben |
|
 |
nemored

Anmeldungsdatum: 22.02.2007 Beiträge: 4704 Wohnort: ~/
|
Verfasst am: 20.06.2010, 19:52 Titel: |
|
|
Ansonsten kannst du auch immer sowas machen wie
Code: | gerundet = INT(ungerundet*1000000 + .5) / 1000000 |
edit: nein, ich sehe, das wirft dasselbe Problem auf.
Aber Format funktioniert doch auch, du musst es bloß in deinen Quelltext schreiben ...
SINGLE hat nicht die Genauigkeit von 7 Nachkommastellen, sondern UNGEFÄHR 7 Stellen (nicht Nachkommastellen!). Die Zahlen werden nicht im Dezimalsystem gerechnet, sondern im Binärsystem.
Noch ein edit:
Was bei mir geklappt hat ist
Code: | dim as integer i = int(e * 1000000 + .5)
print i / 1000000 |
_________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
 |
bubu
Anmeldungsdatum: 21.02.2010 Beiträge: 13
|
Verfasst am: 21.06.2010, 10:54 Titel: |
|
|
Also ich hab das auch schon etwa so gemacht:
Code: |
x=(fix(x*100000))/100000
|
|
|
Nach oben |
|
 |
goooofy
Anmeldungsdatum: 12.09.2005 Beiträge: 69
|
Verfasst am: 21.06.2010, 15:57 Titel: |
|
|
@28398:
Ich brauche den gerundeten Wert in einer Variablen, nicht als Bildschirmausgabe. PRINT USING bringt mir da leider nicht viel.
@nemored:
Laut http://www.freebasic-portal.de/befehlsreferenz/datentypen-383.html hat eine Single eine Genauigkeit von 7 Nachkommastellen. Dann muss diese Angabe wohl falsch sein.
Was meinst du mit "Aber Format funktioniert doch auch, du musst es bloß in deinen Quelltext schreiben ... " Ich habe es doch mit FORMAT$ versucht, gleiches Ergebnis (8436.935649999999).
Dein geposteter Code gibt mir übrigens -2147.483648 aus (mit meinem Wert für e). Da kommt es wohl irgendwie zu einem Überlauf. Runde ich nur auf 5 Nachkommastellen, ist das Ergebnis wieder das ungewünschte
8436.935649999999
Siehe selbst:
Code: | DIM AS DOUBLE e = 2001.12323*8.4322/2
DIM AS INTEGER i = INT(e * 100000 + .5)
PRINT i / 100000 |
@bubu:
Offensichtlich hast du dir meinen Code nicht angesehen, ganau so hatte ich es doch auch versucht. Ergebnis: 8436.935649999999 statt 8436.93565 (Dein Code würde übrigens nur auf 5 Stellen runden)
Hat denn sonst noch jemand eine Idee, wie ich auf mein gewünschtes Ergebnis von 8436.93565 komme? Und bitte mit meinem Wert für e testen, sonst macht das Ganze keinen Sinn. Denn der Rundungsfehler tritt ja nur bei bestimmten Werten auf. |
|
Nach oben |
|
 |
Jojo alter Rang

Anmeldungsdatum: 12.02.2005 Beiträge: 9736 Wohnort: Neben der Festplatte
|
Verfasst am: 21.06.2010, 16:16 Titel: |
|
|
Da du nur eine endliche Menge von Zahlen mit 32 bit darstellen kannst, hat auch nicht jede davon 7 Nachkommastellen und du kannst auch nicht jede Zahl mit 7 Nachkommastellen darstellen - Vielleicht solltest du dir einfach mal das hier durchlesen, um rauszufinden, was mit floats geht und was nicht. _________________ » Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
 |
|
Nach oben |
|
 |
nemored

Anmeldungsdatum: 22.02.2007 Beiträge: 4704 Wohnort: ~/
|
Verfasst am: 21.06.2010, 17:44 Titel: |
|
|
Es handelt sich um die Zahl der möglichen Nachkommastellen. So gesehen ist die Angabe richtig, mag aber durchaus etwas irreführend sein.
Schreib mal in deinen Code
Code: | 'das hier nicht, das ist falsch
'PRINT "Gerundet auf 6 Nachkommastellen (FORMAT$):";e
'aber das ist richtig
PRINT "Gerundet auf 6 Nachkommastellen (FORMAT$):";r1 |
_________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
 |
goooofy
Anmeldungsdatum: 12.09.2005 Beiträge: 69
|
Verfasst am: 26.06.2010, 08:22 Titel: |
|
|
Danke für eure Hinweise!
Ich habe mir den Artikel zu den Floats durchgelesen und weiß nun, dass es sich bei dem ungewünschten Anhängsel um "Artefakte" handelt, die bei Gleitkommazahlen eben einfach entstehen könne, weil sie im Binärsystem nicht exakt dargestellt werden können.
Allerdings habe ich diese nervigen Rundungsungenauigkeiten erst seit Umstieg von Qbasic auf FreeBasic.
Könnt ihr mir denn das folgende dann mal bitte erklären?
Code: | DIM zahl AS DOUBLE
zahl = 8463.93565
PRINT zahl
SLEEP
'Ergebnis FreeBasic: 8463.935649999999
'Ergebnis Qbasic: 8463.93565 |
Ein und derselbe Code, jedoch nur in QBasic das gewünschte Ergebnis. Offensichtlich "rechnet" QBasic doch anders bzw. dort treten diese Artefakte eben einfach nicht auf. Kann das jemand erklären? |
|
Nach oben |
|
 |
Sebastian Administrator

Anmeldungsdatum: 10.09.2004 Beiträge: 5969 Wohnort: Deutschland
|
Verfasst am: 26.06.2010, 12:20 Titel: MBF vs. IEEE |
|
|
Hallo!
goooofy hat Folgendes geschrieben: | [...] erst seit Umstieg von Qbasic auf FreeBasic. [...] Offensichtlich "rechnet" QBasic doch anders [...] |
Das ist in der Tat so. QBasic verwendet intern ein anderes Format für Gleitkommazahlen, eine Microsoft-spezifische Implementierung einer Gleitkomma-Arithmetik namens "MBF" (Microsoft Binary Format). Während QBasic noch MBF verwendet, wird von QuickBASIC (etwa in Version 4.5) bereits der heute gängige IEEE 754 Standard verwendet, sodass du schon in QuickBASIC das gleiche Ergebnis wie in FreeBASIC erhältst.
In der Microsoft Knowledge Base heißt es zu den Versionsunterschieden:
Zitat: | The IEEE floating-point format is found in the Standard and Professional Editions of Microsoft Visual Basic for MS-DOS, version 1.0; in Microsoft QuickBasic for MS-DOS (QB87.EXE coprocessor version only), versions 3.0, 4.0, 4.0b, and 4.5; in Microsoft Basic Compiler for MS-DOS and MS OS/2, versions 6.0 and 6.0b; and in Microsoft Basic Professional Development System (PDS) for MS-DOS and MS OS/2, versions 7.0 and 7.1.
MBF (Microsoft Binary Format) is found in Microsoft QuickBasic for MS-DOS (QB.EXE non-coprocessor version only), versions 1.0, 1.01, 2.0, 2.01, and 3.0, and in Microsoft GW-Basic Interpreter for MS-DOS, versions 3.2, 3.22, and 3.23. |
Sehr ausführliche Informationen zu den Unterschieden der beiden Implementierungen finden sich in folgendem Artikel: http://support.microsoft.com/kb/42980
Viele Grüße!
Sebastian _________________
Die gefährlichsten Familienclans | Opas Leistung muss sich wieder lohnen - für 6 bis 10 Generationen! |
|
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.
|
|