Forum: PC-Programmierung Genauigkeit von Gleitkommazahlen bei c++


von Uschi (Gast)


Lesenswert?

Habe ein Berechnungsprogramm unter C++ durchgeführt!
Weshalb wird

 1,00000000000000009 als  1 dargestellt? und
 0,00000000000000009 als  9e-020 (also genau dargestellt)?

Gruß Uschi

von Gast (Gast)


Lesenswert?

ein wenig quelltext währe nicht schlecht, vllt. versteht dann jemand was 
du meinst.

von Marvin M. (marvin)


Lesenswert?

@Uschi:
Wenn man sich mal mit der Art und Weise der Speicherung von 
Fließkommazahlen beschäftigt, dann wundert das nicht. Z.B. in Wikipedia 
gibt es Artikel hierzu, google ist auch sehr ergiebig.

von Tim T. (tim_taylor) Benutzerseite


Lesenswert?


von Chris (Gast)


Lesenswert?

Zu deiner Frage: Sowohl 1.0 als auch 0.0 können in sowohl double als 
auch in float fehlerfrei dargestellt werden.

von Sven P. (Gast)


Lesenswert?

Und trotzdem: Vergleiche mit '==' bei Fließkomma SIND TABU, Ausnahme 
ist '0', wenn sie explizit zugewiesen wurde, die ist eindeutig.

1 und ein paar andere sind das auch, aber eben nicht alle. Darum Bei 
Vergleichen immer in der Art Betrag(Zahl1 - Zahl2) < Schwelle arbeiten.

von Chris (Gast)


Lesenswert?

> Und trotzdem: Vergleiche mit '==' bei Fließkomma SIND TABU, Ausnahme
> ist '0', wenn sie explizit zugewiesen wurde, die ist eindeutig.

AFAIK garantiert allerdings der C++-Standard nicht, dass folgender 
Code "ja" ausgibt:
1
double x = 0.0, y = 0.0;
2
if(x == y)
3
  cout << "ja";

(Auch wenn das bei den meisten Compilern wohl so sein wird, ist es 
trotzdem implementierungsabhängig).

von Sven P. (Gast)


Lesenswert?

Eigentlich sollte die '0' in der IEEsowieso-Darstellung eindeutig sein, 
so hat man mir das früher(tm) verzapft -- soll aber Fehler nicht 
ausschließen...

von Chris (Gast)


Lesenswert?

Ja, in IEEE754 ist 0.0 eindeutig.
Aber fordert der C++-Standard die IEEE754-Darstellung?

von Uschi (Gast)


Lesenswert?

>>Zu deiner Frage: Sowohl 1.0 als auch 0.0 können in sowohl double als
>>auch in float fehlerfrei dargestellt werden.
Das ist mir klar

Es geht mir um die letzte Ziffer der Zahl! (in meinem fall ne 9!)


wenn ich einer Variablen a den wert
0,00000000000000009 zuweise bekomme ich diesen wert auch wieder mit 
cout<<a;
ausgegeben als 9e-020


wenn ich jedoch einer Variablen b den Wert 1,00000000000000009 zuweise 
bekomme ich über
cout<<b
1 ausgegeben !
wes halb wird hier die letzte tiffer geschluckt ??

von Sven P. (Gast)


Lesenswert?

Zumindest in C wird der nicht gefordert, aber das Makro _STDC_IEC_559_ 
definiert, wenn dieser eingehalten wird.

von Sven P. (Gast)


Lesenswert?

Uschi wrote:
> wenn ich jedoch einer Variablen b den Wert 1,00000000000000009 zuweise
> bekomme ich über
> cout<<b
> 1 ausgegeben !
> wes halb wird hier die letzte tiffer geschluckt ??

Diese IEEE-Floats sind nicht unendlich genau. Das heißt, sie haben 
einerseits eine große Dynamik (ganz große und ganz kleine Zahlen), 
andrerseits können sie aber nicht jeden Wert darstellen. Wenn du da 
1,00000000000000009 angibst, kann es durchaus sein, dass es dafür keine 
Repräsentation gibt und der nächste darstellbare Wert eben 1 ist.

Der Unterschied zwischen 1,00000000000000009 (EINS-komma...) und 
0,00000000000000009 angibst (NULL-komma...) ist halt, dass letztere 
weniger 'Dynamik' hat, wenn man das denn so nennen möchte: Floats nach 
IEEE werden als Basis+Exponent gespeichert. Kannst du auch, nämlich 
diese 'Mal-Zehn-hoch-X'-Schreibweise. Und da siehst du schon ganz 
bildlich den unterschiedlichen Platzbedarf:
0,00000000000000009 --> 9e-20 (kleine Basis [9], kleiner Exponent [-20])
1,00000000000000009 --> tja, irgendwie müssen die Nullen da unterkommen, 
da klappt das mit den kleinen Werten nicht mehr.

von hans (Gast)


Lesenswert?

@Uschi

Schau dir den Link von Tim T. an. Besonderst die Tabellen.
Da siehst du, das Single nur 7-8 genaue Dezimalstellen hat.

Dann zähl mal die Nullen bei 1,0....

gruß hans

von (prx) A. K. (prx)


Lesenswert?

@Uschi: Fliesskommazahlen in Festkommaformat darzustellen dient in 
erster Linie der gezielten Verwirrung des Lesers. Wissenschaftliche 
Darstellung mit Exponent und einer Vorkommstelle kommt der Sache näher.

von Hans-jürgen H. (hjherbert) Benutzerseite


Lesenswert?

http://en.wikipedia.org/wiki/Double_precision

double :

Zwichen 1.0 und
1.0000000000000002220446049250313080847263336181640625
gibt es keinen Zahlen
1.00000000000000009
ist nicht darstellbar wird deswegen als 1.0 abgespeichert.


Außer 0.0 gibt es auch -0.0

Die gibt as als Rechenergebnis f = 0.0 * -1.0 oder f = -1.0 * 0
-0.0 wird dargestellt als 8000000000000000
 0.0 wird dargestellt als 0000000000000000

In Visual Studio 5.0 sind diese Zahlen gleich.

übrigens 0.1 ist auch nicht darstellbar
wird dargestellt als 3FB999999999999A
müsste dargestellt werden als 3FB999999999999999999999999999999999...
aber der Significant (früher "Mantisse" genannt) ist begrenzt auf 52 
bit. Dann wird ein billiger Code abhacken, ein smarter Code wird runden.

Ohne Verluste darstellbar sind alle ganzen Zahlen bis 2 hoch 52

von Chris (Gast)


Lesenswert?

> In Visual Studio 5.0 sind diese Zahlen gleich.

OT: Wo hast du den denn ausgegraben? :-)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.