[C] printf notwendig? / zählen zur 16.777.216

@umbrasaxum

nein, das sind keine Pointer.
(Da ich das jetzt einfach mal schnell zusammengetippt habe, habe ich die & vergessen - sorry)

@endurion

Wenn er hier ein Problem mit der Float-Genauigkeit hätte, dann dürfte er doch nicht bei 12.777.217 normal weiter zählen!
12.777.216 unterscheidet sich von
12.777.215 in genauso vielen Stellen wie 12.777.217!

Btw.: Ja, ich habe den Bereich auch auf double geändert (um genau zu sein, sogar auf long double) - aber das kann doch nicht die Lösung sein.

Ich kanns mir im Moment ja leisten, aber es kann doch nicht jeder hergehen und wegen dieses bescheuerten Zähl-Problem eine höhere Speicher-Allokation verwenden!

shutdown
 
moin


Wenn er hier ein Problem mit der Float-Genauigkeit hätte, dann dürfte er doch nicht bei 12.777.217 normal weiter zählen!

Doch genau das ist das Problem.
Guck dir mal folgende Schleife an:
Code:
for(float i=16777210; i<=16777220; i+=1.000001)
        printf("%f\n", i);

Dazu bekomm ich folgende Ausgabe:
Code:
16777210.000000
16777211.000000
16777212.000000
16777213.000000
16777214.000000
16777215.000000
16777216.000000
16777218.000000
16777220.000000

Edit:
float i = 16777210;
muss nicht gleich
int i = 16777210
sein!


mfg
umbrasaxum
 
einer int Größe kann man doch auch keine 16777216 zuweisen!
---edit:(zwar mögen das eine Compiler annehmen und die Zahl dann tatsächlich anzeigen, aber zumindest bekommst du dann nen Fehler angezeigt)

und da ich ja auch nicht mit int-Größen arbeite, ist das sowieso nicht das Problem

---end edit

wie schon gesagt: ich habe die 16777216 in eine float-Variable eingelesen!

Und bei deinem Code-Schnippsel bekomme ich interessanterweise auch nicht deine Ausgabe, sonder bei 16777216 hänge ich in einer Endlosschleife!

shutdown
 
Zuletzt bearbeitet:
Bin's mit dem Debugger durchgegangen:

i stand auf 12777216 und das ++ hat es nicht verändert. Ich denke, dass da intern evtl. auf ein int gewandelt wird und dann läuft das nicht mehr.
 
Doch! int kann ohne weiteres Werte von -2.147.483.647 bis +2.147.483.647 ab.
usigned int sogar 4.294.967.294

Eine weitverbreiteter Irrtum :-)

int geht von 0 bis 36xxx
was du ansprichst, ist der Punkt, dass viele Compiler standardmäßig int als "LONG INT" abbilden.

Aber wie bereits gesagt: Das ist nicht das Problem! Ich verwende kein int - sondern float!

und bei deinem Code-Schnipsel lande ich in einer Endlosschleife sobald er die 12.777.216 ausgegeben hat und gibt sie dann ständig aus!

shutdown
 
moin


Ein int ist heutzutage 4 Byte groß (abhängig von System), ein float und ein long haben auch 4byte.

Und float hat einfach den Nachteil das es ungenau ist, wie Endurion schon sagte nach der 6. Stelle. Da kann man aber ncihts dran ändern, außer nen anderen Datentyp nehmen


mfg
umbrasaxum
 
shutdown hat gesagt.:
Eine weitverbreiteter Irrtum :-)

int geht von 0 bis 36xxx
was du ansprichst, ist der Punkt, dass viele Compiler standardmäßig int als "LONG INT" abbilden.

Aber wie bereits gesagt: Das ist nicht das Problem! Ich verwende kein int - sondern float!

und bei deinem Code-Schnipsel lande ich in einer Endlosschleife sobald er die 12.777.216 ausgegeben hat und gibt sie dann ständig aus!

shutdown

Float ist das Problem: Kommazahlen können vom Computer einfach nicht alle komplett dargestellt werden. float ist in den 32-bit-Umgebungen üblicherweise ein 32-bit-Datentyp. Davon sind einige Bits für den Exponenten (10^x), einige für die eigentlichen Stellen und eins für das Vorzeichen. Das führt dazu, dass ab einer gewissen Stellen-Anzahl (bei dem üblichen Wert 6 bis 7) die Nachkommastellen nicht mehr stimmen bzw. nicht mehr abgebildet werden können. Das führt dann bei Rechenoperationen ( += 1.0f zum Beispiel) dazu, dass das Ergebnis nicht stimmt. Das passiert in dem Fall, du bist an eine der Stellen geraten. Ärgerlich, aber durch eine Umwandlung auf double lösbar.
 
okay mit Gleitpunktdarstellung kenn ich mich auch aus :-) :

Vorzeichen + Exponent + Mantisse = 32 Bit
1 + 8 + 23 = 32 Bit

Eine Mantisse ist normiert (entweder auf 0, oder auf 1)

in Binärer Darstellung kann man demzufolge alles bis 16.777.215 durch 23 Bit darstellen
für die 16.777.216 bräuchte man dann 24 Bit ==> soweit stimme ich euch zu!

Aber für die 16.777.217 bräuchte ich auch 24 Bit ==> er zählt aber trotzdem danach brav weiter.

Aber trotzdem danke @endurion: Auf die Gleitkommazahlen wäre ich jetzt so schnell nicht gekommen :-)

shutdown

P.S.: Bliebe noch das Problem mit dem printf :-)
 
moin


Ich hab grad mal mit folgendem Code "rumgespielt":
Code:
float i;
int s;

for(i=16777200, s=16777200; i<=4000000000; i++, s++)
{
	if(i!=s)
	{
		printf("\a");
		getch();
	}

    printf("%.40f\n", i);
}

Bei 16777216 kam das erste mal ein Fehler, bei 16777217, dann bei 16777218 ...... 16777250 auch ein Fehler, scheint als wäre 16777216 wirklich (zumindest bei mir) die Schallgrenze für genaues rechnen mit float.


mfg
umbrasaxum
 
Zurück