Unerwartete Ausgabe eines float-Wertes

21/11/2011 - 15:39 von Thomas Wildgruber | Report spam
Hi Community,

folgender Code gibt mir ein unerwartetes Ergebnis zurück:

snip
#include <stdio.h>

int main()
{
int i_value = 16777217;
float f_value = 16777217.0;
printf("The integer is: %i", i_value);
printf("The float is: %f", f_value);
printf("Their equality: %i", i_value == f_value);
}
snap

Die Ausgabe bringt dann folgendes:

snip
The integer is: 16777217
The float is: 16777216.000000
Their equality: 0
snap

Warum fehlt da in der Zeile "The float is:" plötzlich etwas? Es sollte doch
16777217.000000 statt 16777216.000000 angezeigt werden. Oder in welche
Falle bin ich jetzt wieder gelaufen?

Für den Fall, dass die Architektur und Plattform dabei eine Rolle spielen:

snip
Linux debian6-1 2.6.32-5-686
snap

Thx & Bye Tom
"Sie wissen, wir leben im Zeitalter der Abkürzungen. Ehe ist die Kurzform
für lateinische "errare humanum est" ("Irren ist menschlich")." (Robert
Lembke)
 

Lesen sie die antworten

#1 Thomas Rachel
21/11/2011 - 16:41 | Warnen spam
Am 21.11.2011 15:39 schrieb Thomas Wildgruber:

Die Ausgabe bringt dann folgendes:

snip
The integer is: 16777217
The float is: 16777216.000000
Their equality: 0
snap

Warum fehlt da in der Zeile "The float is:" plötzlich etwas? Es
sollte doch 16777217.000000 statt 16777216.000000 angezeigt werden.
Oder in welche Falle bin ich jetzt wieder gelaufen?



In die der Genauigkeit von Fließkommawerten.

Ein Fließkommawert wird als Vorzeichen/Exponent/Mantisse gespeichert.
(http://de.wikipedia.org/wiki/IEEE_754)

Im Falle von float sind das 1+8+23 bits.

Das bedeutet unter anderem, daß, sobald der größte Wert, der in den
Mantissebits gespeichert werden kann, überschritten ist, es am unteren
Ende zu Genauigkeitsproblemen kommt. Das geht genau bei 16777216 los.

Umrechnung:

8388608 = 2 ^ 23
8388609 = 2 ^ 23 + 1 = (1 + 2 ^ (-23)) * 2 ^ 23

Diese 1 + 2 ^ (-23) kann also gerade noch so mit der angegebenen
Mantissenlànge (23) dargestellt werden.

16777216 = 2 ^ 24
16777217 = (1 + 2 ^ (-24)) * 2 ^ 24.
16777218 = (1 + 2 ^ (-23)) * 2 ^ 24.

Bei 16777217 reichts hingegen nicht mehr, 16777218 klappt aber wieder.

Für den Fall, dass die Architektur und Plattform dabei eine Rolle
spielen:

snip
Linux debian6-1 2.6.32-5-686
snap



Das ist bei allen Systemen so, die die üblichen IEEE-Formate anbieten.
(Unter C sogar alle? weiß iuch grade nicht)


HTH,

Thomas

Ähnliche fragen