PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Komisches Verhalten einer For Schleife mit Double Werten


Lord Nikon
2004-06-03, 19:46:24
Hi,
wenn ich eine For-Schleife von -1.0 bis 1.0 in 0.1 Schritten laufen lassen hat die For-Schleife folgende
Werte:

memo
-1
-0,9
-0,8
-0,7
-0,6
-0,5
-0,4
-0,3
-0,2
-0,1
-1,38777878078145E-16
0,0999999999999999
0,2
0,3
0,4
0,5
0,6
0,7
0,8
0,9
1

Ich versteht nicht richtig warum nach -0.1 nicht 0.0 kommt sondern -1,38.
Versteht ihr das?

D-Swat
2004-06-03, 20:34:02
Mit float/double kann man nicht 100%ig genau rechnen.
Die Fehler kommen dadurch das man Gleitkomma Zahlen nicht immer in Bits ausdrücken kann, deswegen gibt es kleine Rundungsfehler.

Ganon
2004-06-03, 22:22:00
Original geschrieben von Lord Nikon
Ich versteht nicht richtig warum nach -0.1 nicht 0.0 kommt sondern -1,38.
Versteht ihr das?

Es sind ja nicht -1,38 sondern: -1,38777878078145E-16

Aber naja. Sind halt die Rundungsfehler die Auftreten können. Warum zählst du eigentlich mit double-Werten? Nehme doch int-Werte um teile dann.

Lord Nikon
2004-06-03, 23:22:30
Original geschrieben von Ganon
Es sind ja nicht -1,38 sondern: -1,38777878078145E-16

Aber naja. Sind halt die Rundungsfehler die Auftreten können. Warum zählst du eigentlich mit double-Werten? Nehme doch int-Werte um teile dann.
Deine vorgeschlagene Lösung habe ich auch sofort dannach verwendet,nachdem ich gesehen,dass es zu den Rundungsfehler kam, aber ich konnte mir nicht erklären, warum es bei so kleinen Beiträgen schon zu den Fehlern kommt.

GloomY
2004-06-04, 00:48:49
Du kannst 0,1 im Zweiersystem nicht exakt darstellen (ähnlich wie du 1/3 im Dezimalsystem nicht exakt darstellen kannst), da dies unendlich viele Stellen benötigt.

Daher hast du bei jeder Berechnung eine gewisse Ungenauigkeit. Du hast Glück, dass am Ende wieder genau das exakte Ergebnis rauskommt, welches theoretisch rauskommen sollte.

btw: Und immer daran denken: FP Zahlen nie mit "==" vergleichen, immer mit ">=" oder "<=" :)

Lord Nikon
2004-06-04, 14:58:56
Original geschrieben von GloomY

btw: Und immer daran denken: FP Zahlen nie mit "==" vergleichen, immer mit ">=" oder "<=" :)
Thx, dass mit dem == ist mir neu,aber hab es ehrlich gesagt auch noch nie ausprobiert.

Matrix316
2004-06-04, 22:24:27
Original geschrieben von Lord Nikon
Thx, dass mit dem == ist mir neu,aber hab es ehrlich gesagt auch noch nie ausprobiert.

Naja, Floating Point Zahlen haben immer Fehler ab einer gewissen Stelle hinter dem Komma bzw. Punkt.

zeckensack
2004-06-04, 22:38:08
Original geschrieben von GloomY
btw: Und immer daran denken: FP Zahlen nie mit "==" vergleichen, immer mit ">=" oder "<=" :) Das kann "==" aber nicht ersetzen. Gegenvorschlag:
static const double epsilon=1.0e-9;
bool is_equal=fabs(a-b)<epsilon;

mrdigital
2004-06-05, 10:10:40
Original geschrieben von zeckensack
Das kann "==" aber nicht ersetzen. Gegenvorschlag:
static const double epsilon=1.0e-9;
bool is_equal=fabs(a-b)<epsilon;
Ziehst du das echt so in deinem Code durch? (Ich finde diese Konstruktion gut, aber leider wird es ein wenig unklar, was hier geschieht, aber so ist nunmal das Problem ;))

Trap
2004-06-05, 11:31:19
Gibt es eine Alternative zum Epsilon? Wenn nicht, muss man es durchziehen.

Nach dem 10. mal schreiben oder lesen ist es nichtmehr unklar.

GloomY
2004-06-06, 23:41:16
Original geschrieben von zeckensack
Das kann "==" aber nicht ersetzen.Von Ersetzen habe ich ja auch nie gesprochen ;D
Original geschrieben von zeckensack
Gegenvorschlag:
static const double epsilon=1.0e-9;
bool is_equal=fabs(a-b)<epsilon;Klar, du hattest anderswo ja auch schon mal eine Methode mit dem relative Fehler gepostet. :) (Ich find's grad' nicht)

ScottManDeath
2004-06-08, 12:53:42
naja, kann man ja so lösen


bool nearly_equal(float a, float b)
{
static const float epsilon = 10e-6;
return fabs(a-b) < epsilon;
}


das ganze dann analog auch für double zahlen


bool nearly_equal(const double& a, const double& b)
{
static const double epsilon = 10e-9;
return fabs(a-b) < epsilon;
}


und dann im code


if ( nearly_equal( a, 2.0f))
....