C++ Wertebereich von Variablen

Abcd12345

Lt. Junior Grade
Registriert
März 2006
Beiträge
483
Hi,

Ich lerne grade die Grundlagen von C++ mit dem Buch "C++ für Spieleprogrammierer". In dem bisher für mich sehr verständlichen Buch bin ich an einer Stelle angelangt, wo ich etwas nicht ganz verstehe bzw noch unklarheiten herschen.

Es geht um Wertebereiche von Variablen. Im Buch wird beschrieben, das diese 256 verschiedene Werte aufnehmen können. Und das sie, wenn man mit der Variabel sowohl positive als auch negative Werte darstellen will der Wertebereich halbiert wird. Man kann dann nur noch Werte von -127 bis +128 darstellen.

Heißt das nun das man der Variabel nur noch eine Zahl zuweißen kann die in dem Bereich liegt oder das man der Variabel 127 negative Werte beliebiger größe und 128 positive Werte Zuweißen kann?
 
Das ist abhänging vom Datentyp der Variable ich vermute mal in dem Fall gehts um "char" bzw. Byte :)
 
Das heißt, dass man dieser Variable nur noch eine Zahl zwischen -127 und +128 zuweisen kann ;)
Wenn Du also versuchst, der Variable -500 oder +300 zuzuweisen, wird dies nicht funktionieren.
 
Es gibt in C/C++ 2 grundlegend verschieden Arten von Variablen.

signed und unsigned

unsigned variablen, also z.B. unsigned char, unsigned int, unsigned long

können nur POSITIVE Werte aufnehmen char(0-255) int(0-65535) long(0-4294967296)

signed variablen können beides POSITIVE und NEGATIVE Werte aufnehmen.
Da die Größe des Variablentyps (also ob char, int oder long) aber gleichbleibt, halbiert sich der
Betrag der benutzbaren Werte (aus den 256 in einer Byte, char variable wir 128)

edit:
float, double ... also "Kommazahlen" fallen dabei raus. Diese Variablentypen sind IMMER signed, also mit Vorzeichenbit.
/edit

Wie du sicher weißt ist 1 Byte = 8 Bit.
Bei signed Variablen wir das erste der 8 Bits als Vorzeichenbit benutzt, demnach hast du dann nur noch 7 Bit für die eigentliche Zahl. 7 Bit entsprechen dann den 128.

Ich hoffe ich konnte dir das etwas verständlich machen, bin nicht so der Erklärbär =)

Wenn du weitere Fragen hast post einfach ich guck dann öfters mal rein.
 
Mit 8 Bit kann man maximal 256 verschiedene Werte darstellen. Wenn du dabei Negative Zahlen darstellen willst ist es logisch das sich dieser Wertebereich jetzt für positive und negative Zeichen aufteilt.
 
die vorderste 0 bei der Binären darstellung steht in dem Fall dafür ob die Zahl positiv oder Negativ dargestellt wird.

D.h. der bereich liegt bei signed vars mit einer größe von 8 bit bzw. 1 byte zwischen -127 - 0 - 128 (2^8 = 256 verschiedene werte)
 
Du kannst mit sizeof(Datentyp); einfach die Größe eines Datentyps in Byte anzeigen lassen. Das musst du dann nurnoch hochrechnen, bei 4 Byte (int) wären das 256^4 = 4294967296. (unsigned)

Funktioniert übrigens mit allem möglichen, zB auch mit Strukturen.
 
Zuletzt bearbeitet: (*duck* ,Int ist 4 Byte groß...)
Servus,

1. es gibt (wie meine vorposter schon angedeutet haben) mehrere Datentypen, die allesamt im Wertebereich beschraenkt sind

2. die Wertebereiche haengen teilweise auch vom Compiler ab (du wirst wahrscheinlich einen 32Bit compiler haben)

3. Wertebereiche der Variablen mit einem 32Bit compiler:

[vorzeichenbehaftet]
char = 8 Bit = -128 .. 127
short = 16 Bit = -32768 .. 32767
int = 32 Bit = -2147483648 .. 2147483647
long = 32 Bit = identisch zu int 32 bit

[Gleitkomma, kodierung etwas schwieriger:
fuer den geneigten leser
IEEE Standard for Binary Floating Point Arithmetic (ANSI/IEEE Std 754-1985) ]
float = 32 Bit = 1.5E-45 .. 3.4E38 [7- 8 Stellen genauigkeit]
double = 64 Bit = 5.0E-324 .. 1.7E308 [15-16 Stellen genauigkeit]
long double = 80 Bit = 1.9E-4951 .. 1.1E4932 [19-20 Stellen genauigkeit]

[ohne vorzeichen, nur positive zahlen moeglich]
unsigned char = 8 Bit = 0 .. 2^8-1 (gesprochen: zwei hoch acht, weis nicht ob du Exponenten in Mathe schon hattest) = 0 .. 2*2*2*2*2*2*2*2 -1 = 0.. 255
unsigned short = 16 bit = 0 .. 2^16-1 = 0 .. 65535
unsigned int = 32 Bit = 0 .. 2^32-1 = 0 .. 4294967295
unsigned long = unsigned int

Man koennte jetzt noch eine formel fuer die notwendigen Bits angeben um eine Zahl zu kodieren das fuehrte aber zu weit.

Prinzipiell wuerde ich dir einfach zu viel ignoranz raten und einfach int zu verwenden, wenn du es nicht gerade mit grossen feldern zu tun hast. Bei Gleitkommazahlen einfach zu double.

Wenn du irgendwan weiter bist kriegst du ein Gefuehl dafuer was du brauchst bzw. weist es genau (was eher anzuraten ist).

Ein wichtiger Hinweis noch (was in machen buechern vergessen wird):

Bei verwendung von Gleitkommazahlen ist darauf zu achten das einige Zahlen nicht genau dargestellt werden koennen:
0.1 kann nicht genau dargestellt werden und ist eigentlich 0.099999999999
Warum ist das wichtig? Ganz einfach:
0.1 + 0.1 + 0.1 ist fuer den rechner UNGLEICH 0.3 weil er sich an der genaugikeitsgrenze verrechnet, 0.1 + 0.1 + 0.1 = 0.29999998 und 0.3 = 0.29999999!!!!!!!
Das kann bei Anfaengern zur Verzweiflung fuehren.

Weiterer hinweis
Falls du mal mit dem debugger in beruehrung kommst und auf Hexadezimalschreibweise umstellst wird bei vorzeichenbehafteten zahlen die -1 nicht mit 0x8001 (16Bit)dargestellt sondern im Sog. 2er Kompliment: 0xffff. Falls dir das nichts sagt, einfach wieder auf Dezimalanzeige umschalten. (die 2er Komplimentdarstellung wird auch manchmal nicht erwaehnt sondern nur behauptet das das vorderste bit fuer den vorzeichenwechsel verantwortlich ist, was zwar insofern stimmt nur die kodierung auf den anderen Bits auch anders ist...)

Und noch etwas (ich liebe die Aenderungsfunktion):
Kauf dir ein C ++ Grundlagenbuch, auch wenn das C++ fuer spieleprogrammierung mit den basics anfaengt (wie jedes verdammte c++ buch, was mich nervt weil ich dafuer immer extra bezahle). Ich hatte bisher zum anfangen immer ein Buch von "Markt + Technik" viele empfehlen auch O'Reilly aber fuer echte anfaenger weis ich nicht ob ich die auch selber empfehlen kann.

So ich hoffe das hat geholfen.
 
Zuletzt bearbeitet:
Hi,

Vielen Dank für die vielen wirklich guten Erklärungen. Ich weiß jetzt genau das was ich wissen wollte. Jedoch ist auch eine neue Frage aufgekommen.

Wieso gibt es überhaupt, die Unterschiedlichen Variabeltypen. Hat es etwas damit zutun um den Code schneller lesbar für den PC zu machen um die Auslastung möglichst gering zu halten? So frei nach dem Motto nicht mehr Abfragen, als nötig ist?
 
Für jede Variable, die du in deinem Programm anlegst, muss Platz im Arbeitsspeicher reserviert werden, der dann für andere Programme nicht mehr nutzbar ist. Wenn du also zum Beispiel einen int verwendest, der ja 4 Byte im Arbeitsspeicher belegt, und du weißt genau, dass du eigentlich mit einem Byte auskommen würdest, weil du nur sehr kleine Zahlen speichern möchtest, dann wäre ein int in dem Sinne Speicherverschwendung von 3 Byte.

Das ist zwar noch nicht gravierend, aber anders sieht das aus, wenn du einen int-Array mit 100000 Elementen anlegen willst. Dann würdest du nämich 100000 x 3 Byte verschwenden, und das ist nicht mehr so ohne.
 
bei gleitkomma und diskreten variablen ist es wohl offensichtlich deswegen geh ich nur auf die Ganzzahligen datentypen ein:

C++ ist zum einen schon etwas aelter und wird heute noch in Systemen eingesetzt in denen der Arbeitsspeicher in Kilobyte(!) gemessen wird nicht in Gigabyte. Da war und ist Speichersparen an der tagesordnung.

Auch in heutigen systemen wuerde es zu problemen kommen: hat man ein 256 Farben Bild das seeeeehr gross ist (z.b. in einer Druckerei) waere es eine ziemliche verschwendung fuer jedes pixel 4Byte zu verwenden da 1 Byte gereicht haette und nur 1/4 so gross ist. Bei einer hohen aufloesung und grossen Bildflaeche kanns auch hier schnell kommen das man hoplahop auf 4GB kommt.

Hoert sich an den Haaren herbeigezogen an? siehe Photoshop, man hat quasi 4 256Bit bilder (rot gruen blau alpha) und mit ein paar effekten und noch zusaetzlichen bildebenen sind da einige hunder MB speicher weg, stell dir vor die wuerden das 4 fache brauchen.

Auch belastet man dann unnoetig die Speicherbandbreite weil du fuer die gleiche information 4 mal so viel daten aus dem ram brauchst.

Die verwendung von kleineren Datentypen macht also auch heute noch sinn, vor allem wenn man mit vielen daten zu tun hat (siehe bildbearbeitung). Was heute deutlich relaxter ist, vor allem auf dem PC, ist dass man bei funktionen die immer nur einemal zur gleichen zeit ausgefuehrt werden statt einem Byte auch ein Int nehmen kann und die 3 Byte kuemmern keinen.

Fuer dich als anfaenger sei gesagt: wenn du nicht mit Feldern (arrays) umgehst, nimm einfach die groesseren datentypen her, wie int und doulbe (long double ist in der verarbeitung deutlich langsamer, haengt mit der bandbreite des cpu zusammen...).

Sobald es passieren kann das du von einem Datentyp oder Object ein paar tausend bis millionen brauchst solltest du aber auf die groesse achten. Hier waere das prinzip: so gross wie noetig, so klein wie moeglich.

Ein anderer Grund ist, man hat den vorteil als programmierer wenn man einen wert hat der ganzzahlig ist und IMMER groesser gleich 0 (anzahl personen in einem Bus) das man das mit dem Typ der Variable schon festlegen kann und wenn man selber einen fehler macht zumindest ein Warning vom compiler erhaelt.
Dieses Konzept wird bei Objektorientierter Programmierung oft angewand.
 
Mal zu den Größen:

Der C++ Standard garantiert lediglich sizeof(char) (==1) <= sizeof( short) <= sizeof(int) <= sizeof( long int)

Wobei int auf jeden Fall größer sein muss als char, damit die IOStreams funktionieren können. Die tatsächlichen Größen variieren je nach Plattform und Compiler und sollte man keinesfalls als fest definiert betrachten.

Außerdem gibt es char in 3 Ausprägungen, signed char, unsigned char und char. Das sind 3 verschiedene Datentypen! Auch wenn char je nach Compilereinstellung signed oder unsigned ist, sorgen die 3 z.B. für 3 verschiedene Ausprägungen bei Templates und nicht etwa zwei (signed und unsigned).
 
Zurück
Oben