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:

Richtig runden mit Gleitkommazahlen

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



Anmeldungsdatum: 17.09.2004
Beiträge: 58

BeitragVerfasst am: 18.12.2008, 19:38    Titel: Richtig runden mit Gleitkommazahlen Antworten mit Zitat

Hallo, ich schreibe gerade an einer Finanzsoftware.
Zu einem Geldbetrag soll der Rabatt berechnet werden.

Code:
CLS
INPUT "Betrag EUR: ", wert#
INPUT "Prozentsatz: ", prozentsatz#

prozentwert# = wert# * prozentsatz# / 100

PRINT USING "##.##"; prozentwert#


Gibt man nun den Betrag 19.90 an und als Prozentsatz 5, so wird als Ergebnis auf zwei Nachkommastellen gerundet 0.99 ausgegeben. Es müssten aber genau 1 sein, da der exakte Prozentwert (0.995) ja aufgerundet wird.

Ich habe mir schon einiges zur Gleitkommaproblematik durchgelesen und auch festgestellt, dass im oben genannten code der tatsächliche Wert für prozentwert# etwa 0.99499999 sind. Das erklärt auch, weshalb abgerundet wird, wenn nur die dritte Nachkommastelle berücksichtigt wird.

Aber wieso zeigt mein Taschenrechner dann genau 0.995 an? Es muss doch möglich sein, mit einem Programm das selbe Ergebnis wie der Taschenrechner zu erhalten. Oder trixt der etwa unbemerkt?
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Lutz Ifer
Grillmeister


Anmeldungsdatum: 23.09.2005
Beiträge: 555

BeitragVerfasst am: 18.12.2008, 21:36    Titel: Antworten mit Zitat

Computer rechnet im Gleitkommaformat IEEE754, dabei wird zwischen den Zahlenbasen 10 und 2 umgerechnet, was Ungenauigkeiten bringt.


Ein Taschenrechner, der im alternativen Gleitkommaformat IEEE854 rechnet, hat diese Ungenauigkeiten nicht (dafür Speicherplatzverschwendung von etwa 2,4%).

Implentationen von sogenannten "Finanz-Gleitkommaformaten" gibts viele, für FREEBasic allerdings nicht nativ (=In die Sprache eingebaut), sondern nur durch die Einbindung von Bibliotheken. Wie die jetzt genau heißen, bin ich allerdings überfragt, weil's mich nicht beschäftigt.
_________________
Wahnsinn ist nur die Antwort einer gesunden Psyche auf eine kranke Gesellschaft.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
dreael
Administrator


Anmeldungsdatum: 10.09.2004
Beiträge: 2507
Wohnort: Hofen SH (Schweiz)

BeitragVerfasst am: 18.12.2008, 21:58    Titel: Antworten mit Zitat

Ohne viel Kommentar:

http://www.dreael.ch/Deutsch/BASIC-Knowhow-Ecke/Gleitkommazahlen.html

Hier werden so ziemlich sämtliche Aspekte vom Titelthema von A biz Z durchgekaut.
_________________
Teste die PC-Sicherheit mit www.sec-check.net
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
steini



Anmeldungsdatum: 17.09.2004
Beiträge: 58

BeitragVerfasst am: 19.12.2008, 00:44    Titel: Antworten mit Zitat

drael, das Problem ist ja nicht, dass ich nicht weiß, wie ich richtig runden soll, sondern dass der Ausgangswert für die Rundungen ungenau ist! In dem Link wird zwar schön erklärt, wie diese Ungenauigkeiten zustande kommen, aber nicht, wie man sie behebt. Oder hab ich da etwas übersehen? Falls ja, gin mir doch bitte nen konkreten Hinweis.

Was die "Finanz-Gleitkommaformate" betrifft, werd ich mich mal schlau machen...

danke erstmal!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
HorstD



Anmeldungsdatum: 01.11.2007
Beiträge: 107

BeitragVerfasst am: 19.12.2008, 03:38    Titel: Antworten mit Zitat

@steini

Versuch's mal damit:




Code:

CLS
INPUT "Betrag EUR: ", wert#
INPUT "Prozentsatz: ", prozentsatz#

prozentwert# = wert# * prozentsatz# / 100

p2#=(prozentwert# * 100 + .5) / 100

PRINT USING "##.##"; prozentwert#

PRINT USING "##.##"; p2#


Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
dreael
Administrator


Anmeldungsdatum: 10.09.2004
Beiträge: 2507
Wohnort: Hofen SH (Schweiz)

BeitragVerfasst am: 19.12.2008, 09:29    Titel: Antworten mit Zitat

@steini:
Ab dem Untertitel "Entwicklung einer Rundungsroutine" gehe ich auf Lösungen ein. Zuvor ist quasi die "Theorie" gefolgt, weshalb es dieses Verhalten gibt.

An Deiner Stelle solltest Du evtl. über die dort dritte diskutierte Variante nachdenken, also intern quasi alle Beträge als beispielsweise *100 grosse Zahl (Faktor abhängig von der kleinsten Währungsstückelung) im Speicher darstellen und somit das Komma nur rein optisch bei der Ausgabe einfügen. Dazu am besten die dortigen Code-Beispiele in FUNCTION-Prozeduren verpacken.
_________________
Teste die PC-Sicherheit mit www.sec-check.net
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
steini



Anmeldungsdatum: 17.09.2004
Beiträge: 58

BeitragVerfasst am: 19.12.2008, 19:17    Titel: Antworten mit Zitat

@HorstD: Die Idee, die du da hast, war mir auch schon gekommen. Einfach einen minimalen Wert dazuaddieren. Dann wird aus den errechneten 0.994999... 0.995 und die Rundung haut hin.
ABER: Was ist, wenn bei anderen Werten rechnerisch nun wirklich 0,994999... rauskommen würde, dann würde er fälschlicherweise auf- statt abrunden.
Im Endeffekt glaube ich, verschiebt man das Problem damit nur. Die konkrete Rechnung geht dann zwar, dafür eine andere aber nicht!

Die Idee von drael, nur mit Ganzzahlen zu rechnen, finde ich echt cool!
Leider hat mein Prog bereits mehrere tausend Zeilen und zig Variablen, da mir der Rundungsfehler erst kürzlich aufgefallen ist. Jetzt nachträglich alles mit Ganzzahlen zu berechnen scheint mir leider unmöglich...

Also wenn jemand vielleicht so eine Bibliothek findet die das kann oder sonst eine ZUVERLÄSSIGE Möglichkeit weiß, würd ich mich sehr freuen!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
nemored



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

BeitragVerfasst am: 20.12.2008, 00:11    Titel: Antworten mit Zitat

Prinzipiell wird es nicht so schwierig sein, eine passende Bibliothek zu erstellen, aber dann kommst du, fürchte ich, um eine Komplettüberarbeitung des Programms trotzdem nicht herum.
_________________
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
volta



Anmeldungsdatum: 04.05.2005
Beiträge: 1875
Wohnort: D59192

BeitragVerfasst am: 22.12.2008, 21:36    Titel: Antworten mit Zitat

Hi,
ob das nun eine "ZUVERLÄSSIGE Möglichkeit" ist kann ich nicht mit Bestimmtheit sagen verwundert
Bei Experimenten mit dem Beispiel von steini fiel mir auch auf das 0.995 in der Anzeige nicht richtig gerundet wurde.
Ich habe dann eine kleine Funktion geschrieben (in FreeBasic) die einmal mit einem sehr kleinen Wert 1E-13 den Umwandlungsfehler korrigiert und dann nach kaufmännischen Gesichtspunkt auf 2 Nachkommastellen rundet.
Code:
Cls
Dim As Double wert=19.90
Dim As Double prozentsatz=5
Dim As Double rabatt
Dim As Double betrag

'http://de.wikipedia.org/wiki/Rundung#Kaufm.C3.A4nnisches_Runden
Function kauf_runden( wert As Double) As Double
  If Sgn(wert) = 0 Then Return wert
  Dim As Double rest = Frac(Abs(wert * 100) + 1e-13)
  If rest > 0.5 Then
    wert = Fix(wert * 100 + Sgn(wert))
  Else
    wert = Fix(wert * 100)
  EndIf
  Function = wert / 100
End Function

Print Using " Brutto ###.## Euro"; wert
rabatt = wert * prozentsatz / 100
Print rabatt

'rabatt = kauf_runden(rabatt)
rabatt = kauf_runden(wert * prozentsatz / 100)
Print rabatt
Print Using "-Rabatt ###.## Euro"; rabatt
betrag = wert - rabatt
Print Using " Betrag ###.## Euro"; betrag
Sleep

_________________
Warnung an Choleriker:
Dieser Beitrag kann Spuren von Ironie & Sarkasmus enthalten.
Zu Risiken & Nebenwirkungen fragen Sie Ihren Therapeuten oder Psychiater.
Nach oben
Benutzer-Profile anzeigen Private Nachricht 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 QBasic. 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