Division wird falsch ausgegeben

Anfängerfragen zum Programmieren mit PureBasic.
heiko
Beiträge: 6
Registriert: 15.08.2008 09:47

Division wird falsch ausgegeben

Beitrag von heiko »

Hallo,

ich habe folgenden Code

Define d.f
d=30/100
Debug d

Ausgegben wird
0.30000001192093

Jetzt möchte ich mit dem Wert aber weiterrechnen, und dann wird es falsch.
Habe ich irgendwelche Einstellungen nicht richtig gemacht ?

Vielen Dank für die Hilfe

Heiko
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7031
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Beitrag von STARGÅTE »

PureBasic Hilfe hat geschrieben: Spezielle Informationen über Fließkommazahlen (Floats und Doubles)

Eine Fließkomma-Zahl (auch Gleitkomma-Zahl, englisch: Floating Point Number) wird in einer Art und Weise gespeichert, die den Binär-Punkt (trennt "Ganzzahlteil" vom "Kommateil") innerhalb der Zahl "gleiten" lässt, wodurch das Speichern sehr großer aber auch sehr kleiner Zahlen (mit vielen Nachkommastellen) möglich wird. Wie auch immer, Sie können nicht sehr große Zahlen mit gleichzeitig sehr hoher Genauigkeit (sozusagen große und kleine Zahlen zur selben Zeit) speichern.

Eine weitere Einschränkung von Fließkomma-Zahlen ist, dass sie stets im Binärmodus arbeiten, weshalb sie nur die Zahlen exakt speichern können, welche mittels Multiplikation oder Division mit 2 ermittelt werden können. Dies ist insbesondere wichtig zu wissen, wenn Sie versuchen, eine Fließkommazahl in einer visuell lesbaren Form darzustellen (oder mit ihr Rechenoperationen auszuführen) - das Speichern von Zahlen wie 0.5 oder 0.125 ist einfach, da sie Divisionen von 2 sind. Das Speichern von Zahlen wie 0.11 ist schwieriger, diese wird möglicherweise als Zahl 0.10999999 gespeichert. Sie können versuchen, nur eine begrenzte Anzahl an (Nachkomma-) Stellen darzustellen, seien Sie aber nicht überrascht, wenn die Darstellung der Zahl anders aussieht, als Sie dies erwarten!

Dies gilt für alle Fließkomma-Zahlen, nicht nur die in PureBasic.

Wie der Name schon sagt, haben Doubles eine doppelte Genauigkeit (64 Bit) gegenüber der einfachen Genauigkeit von Floats (32 Bit). Wenn Sie also genauere Ergebnisse mit Fließkommazahlen erwarten, verwenden Sie Doubles anstelle von Floats.

Der genaue Wertebereich, in dessen Rahmen beim Rechnen mit Floats und Doubles korrekte Ergebnisse erzielt werden, sieht wie folgt aus:

Float: +- 1.175494e-38 bis +- 3.402823e+38
Double: +- 2.2250738585072013e-308 bis +- 1.7976931348623157e+308

Weitere Informationen über den 'IEEE 754' Standard erhalten Sie auf Wikipedia.
Das ist der "Richtige" Wert mit dem du problemlos weiter rechnen kannst.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
THEEX
Beiträge: 804
Registriert: 07.09.2004 03:13

Beitrag von THEEX »

Mist, Stargate war schneller... ^^
Eine Art Query-Planner soll die Ausführung von Map/Reduce-Funktionen in Hadoop stark beschleunigen.
heiko
Beiträge: 6
Registriert: 15.08.2008 09:47

Danke für die rasche Antwort

Beitrag von heiko »

Vielen Dank,

ich denke , dass ich die Nachkommastellen dann ignorieren kann.

Heiko
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Re: Danke für die rasche Antwort

Beitrag von AND51 »

> ich denke , dass ich die Nachkommastellen dann ignorieren kann
Wieso rechnest du dann nicht gleich mit Ganzzahlen? Sprich Longs?
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Benutzeravatar
Deeem2031
Beiträge: 1232
Registriert: 29.08.2004 00:16
Wohnort: Vorm Computer
Kontaktdaten:

Beitrag von Deeem2031 »

Weil 30/100 als Ganzzahl 0 ist - und das ist dann eine nicht mehr vernachlässigbare Abweichung :wink:

Alternativ zu floats könntest du doubles verwenden, also "Define d.d" anstatt "d.f". Diese sind zwar auch nicht 100% genau, aber doch wesentlich genauer als floats.

Natürlich könnte man auch mit Ganzzahlen rechnen, aber dann hat man nur begrenzt Kommastellen und muss jedesmal umrechnen..
Bild
[url=irc://irc.freenode.org/##purebasic.de]irc://irc.freenode.org/##purebasic.de[/url]
Little John

Beitrag von Little John »

Man hat übrigens absolute Präzision beim Speichern und Rechnen, wenn man einen Datentyp "Bruch" mit den entsprechenden Operationen verwendet:

Code: Alles auswählen

Structure Bruch
   Zaehler.l
   Nenner.l
EndStructure

Procedure.l GGT (a.l, b.l)
   ; Berechnet den Größten Gemeinsamen Teiler von a und b.
   ; Wird zum Kürzen von Brüchen benötigt.
EndProcedure

Procedure.l KGV (a.l, b.l)
   ; Berechnet das Kleinste Gemeinsame Vielfache von a und b.
   ; Wird zum Berechnen des Hauptnenners von Brüchen benötigt.
EndProcedure

Procedure BruchAddition (a.Bruch, b.Bruch, *ergebnis.Bruch)
   ; a) Brüche auf den Hauptnenner bringen.

   ; b) Zwei Brüche mit dem selben Nenner werden addiert
   ;    oder subtrahiert, indem die Zähler addiert oder
   ;    subtrahiert werden, und der Nenner beibehalten wird.
EndProcedure

Procedure BruchMultiplikation (a.Bruch, b.Bruch, *ergebnis.Bruch)
   ; Zwei Brüche werden multipliziert, indem beide Zähler und
   ; beide Nenner miteinander multipliziert werden.
EndProcedure

[...]
Falls es solchen Code für PB noch nicht gibt, werde ich das bei Gelegenheit mal schreiben. :)

Gruß, Little John
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Beitrag von NicTheQuick »

Ich hatte da mal was gemacht: Value-Interface
Aber ob man das einem Anfänger zumuten soll?
Little John

Beitrag von Little John »

Hätte mich auch gewundert, wenn das noch keiner gemacht hätte. :)

Ich wollte auf jeden Fall darauf hinweisen, dass es möglich ist mit voller Präzision zu rechnen (wenn die Zahlen nicht zu groß sind).
Den Vorteil "erkauft" man sich quasi um den Preis der größeren Komplexität. Speziell Dein Code kann ja auch noch Komplexe Zahlen bearbeiten, dadurch ist er natürlich noch umfangreicher.

heiko kann ja mal testen, ob er von solchen Berechnungen Kopfschmerzen bekommt. ;)

Gruß, Little John
THEEX
Beiträge: 804
Registriert: 07.09.2004 03:13

Beitrag von THEEX »

Wieso rechnest du dann nicht gleich mit Ganzzahlen? Sprich Longs?
Die Frage, warum float so "ungenau" ist, kam schon öfter auf. Auch wurde meist heiss drüber Diskutiert und es kam wohl immer das Argument, warum man deswegen nicht mit Ganzzahlen rechnet. Man können ja Umwandeln usw...
Eben kann es Situationen geben, bei denen man nicht umrechnen oder ähnliches kann. Ich selbst hab einige Dinge programmiert, bei denen in speziellen Situationen Floats bzw. Doubles umungänglich waren.
Eine Art Query-Planner soll die Ausführung von Map/Reduce-Funktionen in Hadoop stark beschleunigen.
Antworten