Genauigkeit von Floats - Stimmt die Hilfe?

Hier kann alles mögliche diskutiert werden. Themen zu Purebasic sind hier erwünscht.
Flames und Spam kommen ungefragt in den Mülleimer.
marco2007
Beiträge: 906
Registriert: 26.10.2006 13:19
Kontaktdaten:

Genauigkeit von Floats - Stimmt die Hilfe?

Beitrag von marco2007 »

Hi,

Freak schreibt im englischen Forum, daß die Genauigkeit bei Floats nur bei 7 digits liegt: http://www.purebasic.fr/english/viewtop ... ght=digits

Die Hilfe sagt:
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


Paßt das zusammen?

lg
Marco
Windows 11 - PB 6.03 x64
_________________________________
DarkDragon
Beiträge: 6291
Registriert: 29.08.2004 08:37
Computerausstattung: Hoffentlich bald keine mehr
Kontaktdaten:

Beitrag von DarkDragon »

Nunja, es liegt an der Komplexität vom Nachkommateil.

0.25 (= 2 ^ -2) ist komplexer als 0.5 (= 2 ^ -1). Und 0.33333 ist demnach noch viel komplexer.
Angenommen es gäbe einen Algorithmus mit imaginärer Laufzeit O(i * n), dann gilt O((i * n)^2) = O(-1 * n^2) d.h. wenn man diesen Algorithmus verschachtelt ist er fertig, bevor er angefangen hat.
Lord
Beiträge: 324
Registriert: 21.01.2008 19:11

Beitrag von Lord »

Ja, das paßt zusammen.

Wertebereich und Genauigkeit sind zwei verschiedene Paar Schuhe.

Lese Dir doch im obigen Link die Antwort von Demivec durch.

Im Wertebereich sind z.B. gültig:
1234567 oder 123.4567 oder 0.1234567 oder auch 1234567000000

Die Genauigkeit im Rahmen der Binär-/Dezimalumwandlung berücksichtige ich hier einmal nicht.

Gültig wären auch 123456789 oder 1234.56789 oder 0.123456789
Hier wären aber nur die ersten 7 Stellen (im Rahmen der ...) genau:
1234567xx oder 123.4567xx oder 0.1234567xx


Nehme doch einfach einmal vier Byte, bei denen alle Bits gesetzt sind: $FFFFFFFF.
Dieses entspricht Dezimal 4294967295 und umfaßt 10 Stellen. (Eigentlich ja nur 9,5 Stellen, da die erste Stelle maximal 4 sein kann)
Floats werden bei PB in 4 Byte abgespeichert. Für Floats werden aber noch zusätzliche Infos benötigt, damit der größere Wertebereich überstrichen werden kann. Deshalb müssen von den zur Verfügung stehenden Bits sozusagend für die Position des Kommas und das Vorzeichen noch einige Bits 'abgezweigt'' werden, so daß nur noch Bits für 7 gültige Stellen überig bleiben.
Verwenden wir für die 'Verwaltungsaufgaben' ein Byte, benutzen also nur noch 3 Byte für unsere Zahl, so ergibt $FFFFFF nur noch 16777215, also 7 Stellen und die 1 an erster Position (die nur 0 oder 1 annehmen kann).
Das 'Verwaltungsbyte' gibt uns jetzt die Position des Kommas (deshalb Floatingpoint) und das Vorzeichen an.
Das ist ganz vereinfacht das Prinzip und warum bei einem großen Wertebereich nur eine relative gering Zahl von Stellen wirklich gültig sind.
Bild
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

↑ William Kahan über Gleitkommazahlen bei Java (PDF)
...das gilt für ALLE gleitkommazahlen, in jeder Sprache....
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
marco2007
Beiträge: 906
Registriert: 26.10.2006 13:19
Kontaktdaten:

Beitrag von marco2007 »

Lord hat geschrieben:Ja, das paßt zusammen.

Wertebereich und Genauigkeit sind zwei verschiedene Paar Schuhe.


...Klar, aber in der Hilfe steht ja: Korrekte Ergebnisse in diesem Wertebereich. Da hätte ich nie vermutet, daß eine 10-stellige Zahl bereits nach 7 Stellen ungenau sein könnte.

Danke für die Erklärung :allright:
Windows 11 - PB 6.03 x64
_________________________________
Benutzeravatar
Helle
Beiträge: 566
Registriert: 11.11.2004 16:13
Wohnort: Magdeburg

Beitrag von Helle »

Eine Single-Float-Zahl (32 Bit groß) setzt sich so zusammen:
- 1 Bit Vorzeichen
- 8 Bit Exponent
- 23 Bit Mantisse
und eine Double-Float-Zahl (64 Bit groß) so:
- 1 Bit Vorzeichen
- 11 Bit Exponent
- 52 Bit Mantisse
Da normalisierte Zahlen verwendet werden (das 1.Bit der Mantisse ist immer 1 und wird nicht mit angegeben sondern "hinterher" automatisch eingefügt) stehen somit 24 bzw. 53 Bit für die Mantisse zur Verfügung.
Also Single = 2^24 = 16777216 und Double = 2^53 = 9007199254740992. Nachfolger dieser Zahlen können nicht mehr genau aufgelöst werden:

Code: Alles auswählen

;Single
Debug "Single :"
For I = 0 To 14
  S.f = 16777210 + I         ;16777217 kann nicht mehr als Nachfolger berechnet werden, hier fangen die Fehler an
  Debug S
Next

Debug "-----------------------"

;Double
Debug "Double :"
For I = 0 To 14
  D.d = 9007199254740985 + I ;9007199254740993 kann nicht mehr als Nachfolger berechnet werden, hier fangen die Fehler an
  Debug D
Next
Somit wird als Genauigkeit angegeben: Single = 7 und Double = 15 Stellen. Bei Angabe von 16 für Double darf der Wert nicht größer sein als der Wert oben (also Vorsicht !). Man sieht auch Angaben für Single von 7.2 (oder 7.1667 usw.) Stellen, wobei man aber den Hintergrund kennen muss. Selbiges gilt für Double (15.9 usw).

Gruß
Helle
marco2007
Beiträge: 906
Registriert: 26.10.2006 13:19
Kontaktdaten:

Beitrag von marco2007 »

Danke an alle!

Der Beispielcode ist sehr anschaulich! :allright:
Windows 11 - PB 6.03 x64
_________________________________
Antworten