(Gelöst) Sichere Fließkommazahl?

Anfängerfragen zum Programmieren mit PureBasic.
Rebon
Beiträge: 263
Registriert: 20.05.2009 19:13

(Gelöst) Sichere Fließkommazahl?

Beitrag von Rebon »

Hallo,
Es wäre nett, wenn mir jemand schreiben könnte ob diese Verfahrensweise mit Fließkommazahlen sicher,
bzw. so sicher wie möglich ist,
da ich dieses Programm für eine Shop-Webseite schreibe
und diese Fließkommazahl ein Geldbetrag ist.


- Mit Left() und Len() ignoriere ich die letzte Stelle(immer 0) z.B.12,280 = 12,28 oder 421,420 = 421,42
- ReplaceString ersetzt das Komma durch einen Punkt
- Mit ValD wandle ich den String, den ich aus Liste() erhalte in einen Zahlenwert
- Multipliziere den Wert mit 100 und "übergebe" ihn an die Variable Einzelpreis.d

Code: Alles auswählen

Einzelpreis.d = ValD(ReplaceString(Left(Liste(), Len(Liste())-1), ",", ".")) * 100
- Multipliziere Einzelpreis.d mit Stueckzahl(Integer-Variable) z.B. 7 oder 111

Code: Alles auswählen

Einzelpreis.d * Stueckzahl
- Als letztes teile ich den Wert Einzelpreis.d durch 100 und übertrage den Double-Wert mit 2 Stellen nach dem Komma auf den String Gesamtpreis$

Code: Alles auswählen

Gesamtpreis$ = StrD(Einzelpreis.d / 100, 2)
Zuletzt geändert von Rebon am 30.05.2009 03:39, insgesamt 1-mal geändert.
sibru
Beiträge: 265
Registriert: 15.09.2004 18:11
Wohnort: hamburg

Beitrag von sibru »

ja, soweit ok... nur Long anstatt Double, das war´s:

Code: Alles auswählen

Einzelpreis.l = Val(ReplaceString(Left(Liste(), Len(Liste())-1), ",", ".")) * 100

Einzelpreis * Stueckzahl

Gesamtpreis$ = StrD(Einzelpreis / 100, 2) 
(bei Double werden ja auch NachKommaStellen mitberechnet, hast also
nur das Komma um 2 Stellen verbogen. Bei Long gibt´s keine NKS´s...)

Gruss SiBru
Bild Bild
Rebon
Beiträge: 263
Registriert: 20.05.2009 19:13

Beitrag von Rebon »

Danke dir Sibru! :allright:
Rebon
Beiträge: 263
Registriert: 20.05.2009 19:13

Beitrag von Rebon »

@Sibru

Du meintest sicher ValD oder?:

Code: Alles auswählen

Einzelpreis.l = ValD(ReplaceString(Left(Liste(), Len(Liste())-1), ",", ".")) * 100
Trotzdem, deine Antwort war sehr informativ! :)
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

Jede Fließkommazahl hat eine begrenzte Genauigkeit.
bei Double ist sie wesentlich geringer, aber auch vorhanden.

für Währungsbeträge würde ich eher dazu raten, mit Integer zu arbeiten, also mit Quad, und stattdessen mit 1/10 cent zu rechnen.

für normale Kassenfunktionen kann auch mal ganze Cent genügen,
allerdings weiß ich nicht, wie präzise die Mehrwertsteuer ausgewiesen werden muss,
mit 1/10 Cent solltest du allerdings auf der sicheren Seite sein.

Für Zinsgeschäfte wären 1/100 Cent besser, auch da kenne ich die Vorschriften nicht.

Aber ganz grundsätzlich ist eine Integer immer genau, bis sie oben anstößt.
eine Float stößt nie oben an, dafür wird sie immer ungenauer.

kleine Demo:

Code: Alles auswählen

VInt.l = Pow( 2, 24 ) -5
CInt.l = 1

VFlo.f = VInt
CFlo.f = 1

For n=0 To 9
  VInt + CInt
  Debug "Integer: " + Str( VInt )
  VFlo + CFlo
  Debug "Float: " + StrF( VFlo )
Next
bis 2^24-1 funktioniert dir Float auf 1.0 genau, darüber nicht mehr, die Addition wird nicht mehr korrekt ausgeführt.
das liegt daran, dass bei einer 32bit Float 23bit für die Mantisse verwendet werden.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Rebon
Beiträge: 263
Registriert: 20.05.2009 19:13

Beitrag von Rebon »

Auch danke an dich Kaeru! :allright:
Zwar hab ich keine Ahnung, was z.B. Pow
bedeutet, aber ich werds herausfinden (PB-Help).
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

das erzeugt nur 2^24...

statt Pow( 2, 24) -5 hätte ich auch 16777211 schreiben können...
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Rebon
Beiträge: 263
Registriert: 20.05.2009 19:13

Beitrag von Rebon »

Also, wenn ich deine Demo richtig verstanden habe,
dann geht die Genauigkeit bei Float bis 16777216.000000.
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

die Genauigkeit um 2^0 also 1

wenn du auf 0.01 genau rechnen willst, ist schluss bei 167772.11
wenn du auf 0.001 genau rechnen willst, ist schluss bei 1677.7211

wie gesagt, Double ist zwar wesentlich genauer, aber auch dort greift irgendwann die ungenauigkeit.

deswegen benutze lieber Quads und rechne mit 1/10 Cent,
dann sind alle Beträge bis zur Summe ±9.223.372.036.854.775,807 € wirklich genau.

PS:
bei einer Integer bekommst du einen klaren Überlauf, das merkt man ganz deutlich.

bei Fließkomma bekommt man auch weiterhin richtig aussehende Zahlen zurück,
sie stimmen nur nicht mehr, wie du an der Demo gut sehen kannst.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Rebon
Beiträge: 263
Registriert: 20.05.2009 19:13

Beitrag von Rebon »

Kaeru Gaman hat geschrieben: deswegen benutze lieber Quads und rechne mit 1/10 Cent,
dann sind alle Beträge bis zur Summe ±9.223.372.036.854.775,807 € wirklich genau.
Ich werd's versuchen, muß mich aber erst noch genauer
über Quads informieren.
Da ich im meinem Programm, später noch die Mehrwertsteuer
ausrechnen muß, ist deine Hilfe sehr nützlich!
Danke nochmal! :allright:

Edit: Ich hab mich in der Help von PB verlesen, muß mich nicht über Quads informieren. :mrgreen:
Hab da was mit BinQ bzw. dem Binärformat gelesen.
Zuletzt geändert von Rebon am 30.05.2009 00:12, insgesamt 1-mal geändert.
Antworten