Problem mit Schleife
-
SeppJ schrieb:
Was ist bei dir denn
sizeof(long long int)
? Wenn das 8 ist, solltest duunsigned long long int
nehmen. Wenn es weniger als 8 ist, hast du ein Problem.Im Notfall gibt es ja noch double. Nur typischerweise kann bei so riesigen Zahlen nicht mehr exakt gerechnet werden. Aber der Fehler sollte hier nicht wirklich ins gewicht Fallen. Ob man hier drei Milliarden Eisenbahnwagons oder drei Milliarden und einen benötigt...
-
Ja, war zu faul, nachzugucken, was die Mindestgröße von long long ist. Bei negativem Ergebnis lag ein Überlauf nahe. Und tut es immer noch: 2^64-1 passt nicht mehr in signed long long, wenn dieser nur die Mindestlänge hat. Bei unsigned long long würde es genau passen.
Und double wäre eher unschön, da double precission normalerweise eine 53 Bit Mantisse bedeutet, wo das erst recht nicht (genau) reinpasst.
-
Also zusammengefasst:
#include <iostream> using namespace std; int main () { long long int reiskorn = 1; // Zahlenbereich anpassen short int felder; // felder -> initialisieren do { reiskorn = reiskorn * 2; // das ist ein Korn zu viel -> korrigieren felder = felder + 1; } while (felder != 63); // wie viele Felder hat ein Schachspiel? cout << reiskorn ; system("PAUSE"); }
Der gcc 4.4.? gibt eine Warnung long long ist noch nicht genormt.
Das Ergebnis zeigt aber keine Auffälligkeiten.
-
Auf meinem System unterscheidet sich die Zahl der Kilometer beim Vergleich unsigned long long und double um eins.
Es ist zwar ein Fehler, aber dennoch mMn vernachlässigbar.
-
Vicious Falcon schrieb:
Auf meinem System unterscheidet sich die Zahl der Kilometer beim Vergleich unsigned long long und double um eins.
Es ist zwar ein Fehler, aber dennoch mMn vernachlässigbar.Wie hast du das gemessen? Das mag ich irgendwie nicht glauben.
-
Zwei Aufrufe einer Templatefunktion, ich hatte aber /=15 statt *=15 geschrieben. Da lag die Differenz der Kilometer bei 1.
Es ist mir aber gerade erst aufgefallen, als ich meinen Code anhand der Aufgabenstellung noch einmal kontrolliert habe.
-
Vicious Falcon schrieb:
Zwei Aufrufe einer Templatefunktion, ich hatte aber /=15 statt *=15 geschrieben. Da lag die Differenz der Kilometer bei 1.
Es ist mir aber gerade erst aufgefallen, als ich meinen Code anhand der Aufgabenstellung noch einmal kontrolliert habe.
Beim ersten Mal habe ich ja noch gedacht, dass du versehentlich "Kilometer" statt Körner geschrieben hättest, aber nun bin ich komplett verwirrt.
-
Vicious Falcon bezieht sich wohl auf die Länge des Zuges(letze Teilaufgabe).
Die Abweichung der Körneranzahl bei int zu double beträgt 385. Dabei wurde der double-wert aufgerundet.
-
Wieso, die Reihenfolge ist doch
Körner -> Gramm -> Tonnen -> Wagen -> Länge (m) -> Länge (km)
Zwischen Wagen und Länge (m) hat sich der Fehler eingeschlichen.
-
do { reiskorn = reiskorn * 2; felder = felder + 1; } while (felder != 63);
Auch wenn die Anzahl der Multiplikationen *2 stimmen mag (63), berechnet es die Anzahl der Reiskörner auf dem aktuellen Feld. Das dürfte von der Gesamtsumme ein wenig abweichen und somit den armen Fahrdienstleiter dann doch etwas ins Schwitzen bringen...
Wenn man das Ganze mal binär und "von Hand" betrachtet, ist das recht einfach zu verstehen (entspricht in etwa der bereits genannten Formel):
1. Feld: 1 Reiskorn 2. Feld: 10 3. Feld: 100 ... ------------------- Summe ...111111111
Da bei jeder Multiplikation *2 im Prinzip ja nur ein Bitshift der 1 stattfindet, ist leicht ersichtlich, dass die 1 nach 63 Bitshifts, also auf dem 64. Feld, im obersten Bit des
unsigned long long
angekommen ist. Jetzt müssen nur eben alle Bits addiert werden. Sollte die schöne Zahl0xFFFFFFFFFFFFFFFF
ergeben.Ergänzung: Wenn man tatsächlich ein 2^64 -1 versucht, wird klar, dass 2^64 = 0 ergibt (zumindest wenn
unsigned long long
64 Bit groß ist.). Das Ergebnis ist dann alsunsigned
ausgedrückt -1 bzw. alssigned
die genannte Zahl. Die -1 rettet alles...Edit: ein paarmal die 63 und 64 verwechselt...