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:

runden auf 6 Nachkommastellen

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



Anmeldungsdatum: 12.09.2005
Beiträge: 69

BeitragVerfasst am: 20.06.2010, 19:02    Titel: runden auf 6 Nachkommastellen Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
28398



Anmeldungsdatum: 25.04.2008
Beiträge: 1917

BeitragVerfasst am: 20.06.2010, 19:23    Titel: Antworten mit Zitat

http://www.freebasic-portal.de/befehlsreferenz/print-using-485.html
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
nemored



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

BeitragVerfasst am: 20.06.2010, 19:52    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
bubu



Anmeldungsdatum: 21.02.2010
Beiträge: 13

BeitragVerfasst am: 21.06.2010, 10:54    Titel: Antworten mit Zitat

Also ich hab das auch schon etwa so gemacht:
Code:

x=(fix(x*100000))/100000
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
goooofy



Anmeldungsdatum: 12.09.2005
Beiträge: 69

BeitragVerfasst am: 21.06.2010, 15:57    Titel: Antworten mit Zitat

@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
Benutzer-Profile anzeigen Private Nachricht senden
Jojo
alter Rang


Anmeldungsdatum: 12.02.2005
Beiträge: 9736
Wohnort: Neben der Festplatte

BeitragVerfasst am: 21.06.2010, 16:16    Titel: Antworten mit Zitat

goooofy hat Folgendes geschrieben:

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.

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
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
nemored



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

BeitragVerfasst am: 21.06.2010, 17:44    Titel: Antworten mit Zitat

goooofy hat Folgendes geschrieben:
@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.

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
Benutzer-Profile anzeigen Private Nachricht senden
goooofy



Anmeldungsdatum: 12.09.2005
Beiträge: 69

BeitragVerfasst am: 26.06.2010, 08:22    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
Sebastian
Administrator


Anmeldungsdatum: 10.09.2004
Beiträge: 5969
Wohnort: Deutschland

BeitragVerfasst am: 26.06.2010, 12:20    Titel: MBF vs. IEEE Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC. 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