Unsigned Long = Unsigned Int! Warum?
-
Hallo, ich hab durch Zufall heute den Artickel über Zufallszahlen: http://www.c-plusplus.net/forum/viewtopic-var-t-is-172876.html entdeckt. Und hab Versucht mir eine eigene Klasse zur Erzeugung von Zufallszahlen zu schreiben.
Bei meinen Versuchen mit größeren (Zufalls-) Zahlen ist mir folgendes aufgefallen :
http://img5.imagebanana.com/view/055a5wfb/ULongUInt.dibDie Varable L (unsigned long) müsste größer sein als die Variable I (unsigned int), da ich beiden den größtmöglichen Wert für ihre Typen (ulong: 0xffffffffffffffff, uint: 0xffffffff, LIMITS.h) zugewiesen hab, sie haben aber beide den gleichen Wert. Und warum gibt der Debugger mir keinen Fehler in Zeile 9 aus, in der der Varialbe I ein größerer Wert zugewiesen wird, als sie aufnehmen kann.
Ich weiß nicht ob das wichtig ist aber egal: Ich benutze noch die Beta von Windows 7(Evaluierungskopie Build 7100).MfG Icon
-
Icon² schrieb:
Die Varable L (unsigned long) müsste größer sein als die Variable I (unsigned int) [...]
Nein, müsste sie nicht. Der C++-Standard erlaubt durchaus, dass
unsigned longundunsigned intdie selbe Grösse besitzen.Icon² schrieb:
[...] da ich beiden den größtmöglichen Wert für ihre Typen (ulong: 0xffffffffffffffff, uint: 0xffffffff, LIMITS.h) zugewiesen hab
Wenn du
<limits.h>inkludierst (korrekt wäre eigentlich<climits>, C++-Standardheader besitzen keine Dateiendung), solltest du auch die Makros einsetzen und nicht mit Literalen wie0xffffffffhantieren...
-
Was heißt "Literale" ? Ich hab halt L = 0xFF..... geschrieben, wobei ich die selbe Anzahl an Fs genommen habe wie in LIMITS.H.
Ja ich weiß dass der C++ Standard nur vorschreibt dass der Werte Brereich einer unsigned long größer oder gleich groß wie der Werte Bereich einer unsinged int.
Aber ich benutze Windows 7 x64 und MSVC++ und dann müsste unsigned long doch eigentlich um den wert aus LIMITS.H größer sein, oder nicht?
-
Icon² schrieb:
Was heißt "Literale" ?
Literale nennt man temporäre Objekte, deren Wert du gleich in den Code schreibst. Beispiele:
"hallo" // Stringliteral 77ul // unsigned long-Literal 2.5 // double-Literal false // bool-LiteralIcon² schrieb:
Ich hab halt L = 0xFF..... geschrieben, wobei ich die selbe Anzahl an Fs genommen habe wie in LIMITS.H.
Was denkst du, wofür der Header ist? Sicher nicht, um dessen Inhalt abzuschreiben.

Benutze wie gesagt die dort definierten Makros. Welche das sind, findest du zum Beispiel auf www.cplusplus.com heraus.Icon² schrieb:
Ja ich weiß dass der C++ Standard nur vorschreibt dass der Werte Brereich einer unsigned long größer oder gleich groß wie der Werte Bereich einer unsinged int.
Aber ich benutze Windows 7 x64 und MSVC++ und dann müsste unsigned long doch eigentlich um den wert aus LIMITS.H größer sein, oder nicht?Müsste nicht, das ist wiederum compilerabhängig. Nur weil du ein 64-Bit-System verwendest, heisst das noch nicht, dass
long64 Bit gross sein muss (es ist allerdings wahrscheinlicher). Eventuell kannst du die Grösse in der IDE konfigurieren (soviel ich weiss, kannst du zumindest einstellen, ob du für 32 oder 64 Bit kompilierst).Ansonsten benutze den Typen
unsigned long long, dieser ist allerdings nicht im C++-Standard enthalten.
-
<Korinthenkacker-Mode>
Mit Ausnahme von String-Literalen sind Literale keine Objekte nach C++ Standard-Definition von "Objekt".
</Korinthenkacker-Mode>Sonst empfehle ich immer wieder gerne die Seite Integer Types in C and C++.
Ansonsten benutze den Typen
unsigned long long, dieser ist allerdings nicht im C++-Standard enthalten.Oder von <boost/cstdint.hpp> den Typalias boost::uint_least64_t wenn man mindestens 64 Bits braucht.
-
Sebastian Pizer schrieb:
<Korinthenkacker-Mode>
Mit Ausnahme von String-Literalen sind Literale keine Objekte nach C++ Standard-Definition von "Objekt".
</Korinthenkacker-Mode>Und wie kommst du darauf, das Stringliterale, die in C++ den Typ char* haben,
Objekte wären und das Floatliteral 4.5f kein Objekt?Wenn schon, dann richtig

-
Sebastian Pizer schrieb:
<Korinthenkacker-Mode>
Mit Ausnahme von String-Literalen sind Literale keine Objekte nach C++ Standard-Definition von "Objekt".
</Korinthenkacker-Mode>Stimmt, ich dachte gerade nicht mehr daran, dass skalare RValues ja speziell behandelt werden...
branleb schrieb:
Und wie kommst du darauf, das Stringliterale, die in C++ den Typ char* haben,
Objekte wären und das Floatliteral 4.5f kein Objekt?Wenn schon, dann richtig

Das gilt auch für dich. Stringliterale haben den Typ
const char[size].
-
Nexus schrieb:
branleb schrieb:
Und wie kommst du darauf, das Stringliterale, die in C++ den Typ char* haben,
Objekte wären und das Floatliteral 4.5f kein Objekt?Wenn schon, dann richtig

Das gilt auch für dich. Stringliterale haben den Typ
const char[size].Verdammt - hast recht ...
-
branleb schrieb:
Sebastian Pizer schrieb:
<Korinthenkacker-Mode>
Mit Ausnahme von String-Literalen sind Literale keine Objekte nach C++ Standard-Definition von "Objekt".
</Korinthenkacker-Mode>Und wie kommst du darauf, das Stringliterale, die in C++ den Typ char* haben,
Hamse nicht. String-Literale sind Lvalue-Ausdrücke vom Typ
const char[N], wobei N die Zahl der Zeichen (inklusive Nullterminator) sind. Alle anderen Literale sind Rvalue-Ausdrücke skalarer Typen. Die Definition von "Objekt" kann man in Abschnitt 1.8 nachlesen:The constructs in a C++ program create, destroy, refer to, access, and manipulate objects. An object is a region of storage. An object is created by a definition, by a new-expression or by the implementation when needed. [...]
Und dann gibts noch Abschnitt 3.10:
Every expression is either an lvalue or an rvalue.
An lvalue refers to an object or a function. Some rvalue expressions -- those of class or cv-qualified class type -- also refer to objects. [...]
Und dann gibts noch Abschnitt 5.1
[...]
A literal is a primary expression. Its type depends on its form. A string literal is an lvalue; all other literals are rvalues.
[...]Ob man jetzt skalare Rvalues als "Objekte" bezeichnen kann .... naja, das ist zumindest eine Grauzone, würde ich sagen.
Gruß,
SP
-
Wenn ich anstatt einer "unsigned long" eine "unsigned long long" Variable nehme dann funktionierts.
unsigned int I = UINT_MAX; // ==> 4294967295 unsigned long L = ULONG_MAX; // ==> 4294967295 unsigned long long LL = ULLONG_MAX; // ==> 18446744073709551615Das heißt, dass bei meinem MSVC++ Compiler "long" = "int" ist.
-
Icon² schrieb:
unsigned int I = UINT_MAX; // ==> 4294967295 unsigned long L = ULONG_MAX; // ==> 4294967295 unsigned long long LL = ULLONG_MAX; // ==> 18446744073709551615Das heißt, dass bei meinem MSVC++ Compiler "long" = "int" ist.
Kommt drauf an, was Du damit meinst.
long intundintsind zwei verschiedene Typen. Du kannst zB Funktionen mit ihnen überladen oder sie als Template-Parameter benutzen. vector<int> und vector<long> sind dementsprechend auch zwei verschiedene Typen. long ist also niemals ein "typedef" (Alias) für int.
-
@Sebastian Pizer: Ja, klar hab mich nur undeutlich ausgedrückt. Ich meinte natürlich, dass "long" und "int" denselben Maximalen Wert haben.
-
Icon² schrieb:
Das heißt, dass bei meinem MSVC++ Compiler "long" = "int" ist.
Von solchen "Annahmen" sollte man grundsätzlich die Finger lassen, das geht irgend wann schief. Denn im 32Bit und im 64Bit Modus sind die die Typen unterschiedlich definiert, d.h. was im 32Bit Modus gültig ist, muß im 64Bit Modus längst nicht gültig sein.
-
~john schrieb:
Denn im 32Bit und im 64Bit Modus sind die die Typen unterschiedlich definiert, d.h. was im 32Bit Modus gültig ist, muß im 64Bit Modus längst nicht gültig sein.
Und von Compiler zu Compiler kann es ebenfalls unterschiedlich sein...
-
Das Beste ist sowieso, man verlässt sich nicht auf irgendwelche implementierungsabhängigen Dinge. Gerade für sowas gibts ja
sizeofund die Header<limits>bzw.<climits>. Im Notfall hat man immer noch Static-Assertions zur Verfügung.