Forum: Mikrocontroller und Digitale Elektronik Wie groß ist uint_8


von Cooler Datentyp (Gast)


Lesenswert?

Hallo,

keine Angst, so blöde wie der Titel verheissen lässt ist die folgende 
Frage nicht:


Ich weiss, dass ein uint8_t 8Bit hat, aber in Wahrheit nimmt er doch 
/(mindestens) 9 Bit realen Speicherplatz ein, da irgendwo gespeichert 
sein muss, ob das Vorzeichenbit als solches zu behandeln ist.

Für jeden Datentyp muss bekannt sein, wieviele gültige Bits es gibt (8) 
und darüber hinaus ob es einen Offset um 2^(n/2) gibt...

Welches Informationen sind noch in den Datentypen gespeichert, die als 
Overhead mit getragen werden müssen und den eigentlichen Speicherbereich 
größer machen, als er eigentlich ist?

von Falk B. (falk)


Lesenswert?

@  Cooler Datentyp (Gast)

>Ich weiss, dass ein uint8_t 8Bit hat, aber in Wahrheit nimmt er doch
>/(mindestens) 9 Bit realen Speicherplatz ein,

Nö.

> da irgendwo gespeichert sein muss, ob das Vorzeichenbit als solches zu
> behandeln ist.

Kaum. Was denkst du, was das u im Namen bedeutet? U wie unsigned?

>Für jeden Datentyp muss bekannt sein, wieviele gültige Bits es gibt (8)
>und darüber hinaus ob es einen Offset um 2^(n/2) gibt...

Klar. Der vorzeichenmächtige Bruder heißt int8_t.

>Welches Informationen sind noch in den Datentypen gespeichert, die als
>Overhead mit getragen werden müssen und den eigentlichen Speicherbereich
>größer machen, als er eigentlich ist?

Gar keine. Sie sind implizit.

MFG
Falk

von Achim M. (minifloat)


Lesenswert?

Das U oder eben Nicht-U sagt bloß dem Compiler, wie er mit dieser Zahl 
umzugehen hat. Das ist insbesondere bei der Bewertung von Bedingungen 
wie bei if() und bei anstehenden Multiplikationen und Divisionen der 
Fall.

"-1" ist ja nichts anderes als eine "255"...meint man
1
uint8_t foo = 255;
2
3
// Fall 1, unsigned wird also als 255 behandelt
4
// und der Block nicht ausgeführt
5
if(foo < 0)
6
{
7
   //Tue dies und jenes in diesem Block
8
   printf("Block Eins ausgefuehrt\n");
9
}
10
11
// Fall 2, auf signed gecastet, wird nun als -1 behandelt
12
// und der Block wird ausgeführt
13
if((int8t) foo < 0)
14
{
15
   //Tue etwas anderes in diesem Block
16
   printf("Block Zwei ausgefuehrt\n");
17
}
mfg mf

von Cooler Datentyp (Gast)


Lesenswert?

Ja und wo bitte in meinem Mikrocontroller sitzt mein Compiler? 
Nirgendwo!

Im Mokrocontroller werden die Datentypen doch nochmal codiert, d.h. 
neben den eigentlichen Bits muss irgendwo zusätzlich gespeichert sein, 
wie die einzelnen Bits zu interpretieren sind, wie lang ein Typ ist, wo 
das nächste anfängt...

Wenn ich auf einem Display einen int8 und einen char in einer for 
schleife hochzähle und ihn mir ausgebe, dann bekomme ich beim int8 
Beträge von maximal 128 wohingegen ich beim uint8 Beträge bis zu 255 
erhalte.

Diese Information muss doch irgendwo hinterlegt sein.

von g457 (Gast)


Lesenswert?

> Diese Information muss doch irgendwo hinterlegt sein.

Ja, und zwar in dem Programm das wo Dein Compiler (ggf. auf dem 
Hostsystem) erzeugt hat :-)

HTH

von Achim M. (minifloat)


Lesenswert?

Cooler Datentyp schrieb:
> Wenn ich auf einem Display einen int8 und einen char in einer for
> schleife hochzähle und ihn mir ausgebe, dann bekomme ich beim int8
> Beträge von maximal 128 wohingegen ich beim uint8 Beträge bis zu 255
> erhalte.

Implizite Typumwandlung ist hier das Stichwort. Da wird umgewandelt z.B. 
in int16_t, obwohl mans im Quellcode "nicht sieht". mfg mf

von Klaus (Gast)


Lesenswert?

Cooler Datentyp schrieb:
> Ja und wo bitte in meinem Mikrocontroller sitzt mein Compiler?
> Nirgendwo!
>
> Im Mokrocontroller werden die Datentypen doch nochmal codiert, d.h.
> neben den eigentlichen Bits muss irgendwo zusätzlich gespeichert sein,
> wie die einzelnen Bits zu interpretieren sind, wie lang ein Typ ist, wo
> das nächste anfängt...

Für solche Frage ist es äußerst erhellend, wenn man mal etwas Assembler 
programmiert. Dann würdest du sehen, dass z. B. die Information über 
signed/unsigned nicht in den Daten gespeichert ist, sondern es lediglich 
eine Frage der Interpretation beim Zugriff auf die Variable ist. Es gibt 
Befehle, die die 8 Bits als singed interpretieren. Und es gibt welche, 
die sie als unsigned interpretieren. Welcher davon im Code auftaucht 
entscheidet der Compiler, je nachdem ob da z. B. uint8_t oder int8_t 
steht.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Cooler Datentyp schrieb:
> Ja und wo bitte in meinem Mikrocontroller sitzt mein Compiler?
> Nirgendwo!
>
> Im Mokrocontroller werden die Datentypen doch nochmal codiert, d.h.
> neben den eigentlichen Bits muss irgendwo zusätzlich gespeichert sein,
> wie die einzelnen Bits zu interpretieren sind, wie lang ein Typ ist, wo
> das nächste anfängt...
>
> Wenn ich auf einem Display einen int8 und einen char in einer for
> schleife hochzähle und ihn mir ausgebe, dann bekomme ich beim int8
> Beträge von maximal 128 wohingegen ich beim uint8 Beträge bis zu 255
> erhalte.
>
> Diese Information muss doch irgendwo hinterlegt sein.

Nein, die Daten werden nicht nochmals codiert.

Die Types legen fest, wie breit eine Variable ist und wie damit 
umzugehen ist.  Ein Teil der Typinformation landel also sozusagen 
"implizit" im erzeugten Code:
1
char c;
2
3
void set_u (unsigned char x)
4
{
5
    if (x < 100)
6
        c = 0;
7
}
8
9
void set_s (signed char x)
10
{
11
    if (x < 100)
12
        c = 0;
13
}

Obwohl es in der Funktion der "gleiche" Code ist, wird der 
Vergleich/Sprung anders ausgeführt: einmal in einer signed- und einmal 
in der unsigned-Variante:
1
set_u:
2
  cpi r24,lo8(100)   ;  x,
3
  brsh .L1
4
  sts c,__zero_reg__   ;  c,
5
.L1:
6
  ret
7
8
set_s:
9
  cpi r24,lo8(100)   ;  x,
10
  brge .L3
11
  sts c,__zero_reg__   ;  c,
12
.L3:
13
  ret

von Andreas K. (derandi)


Lesenswert?

8 Bit = 2^8 = 256
7 Bit = 2^7 = 128
Fällt dir was auf?
Eins der acht Bit wird bei den signed-typen fürs Vorzeichen verwendet.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Übrigens kann das einige Fallstricke enthalten, wie im folgenden 
Beispiel, das Überlauf testen möchte:
1
char c;
2
3
void set_u (unsigned int x)
4
{
5
    if (x + 10 < x)
6
        c = 0;
7
}
8
9
void set_s (signed int x)
10
{
11
    if (x + 10 < x)
12
        c = 0;
13
}

wird übersetzt zu:
1
set_u:
2
  ldi r18,hi8(-10)
3
  cpi r24,lo8(-10)   ;  x,
4
  cpc r25,r18   ;  x,
5
  brlo .L1
6
  sts c,__zero_reg__   ;  c,
7
.L1:
8
  ret
9
10
set_s:
11
  ret

Hausaufgabe: Warum wird für set_s kein Code erzeugt?

von Karl H. (kbuchegg)


Lesenswert?

Johann L. schrieb:

> Hausaufgabe: Warum wird für set_s kein Code erzeugt?


<durch die Zähne pfeif>

Das erkennt der gcc. Du siehst mich verblüfft.

von A.R.Biter (Gast)


Lesenswert?

Gebt euch doch nicht sooo viel Mühe!

Ich wette, dass Cooler Datentyp sich nicht mehr meldet,
sobald er kapiert hat, dass auch die besten Forums-
Beiträge keine irrige Annahme bestätigen können...

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Karl Heinz Buchegger schrieb:
> Johann L. schrieb:
>
>> Hausaufgabe: Warum wird für set_s kein Code erzeugt?
>
> <durch die Zähne pfeif>
>
> Das erkennt der gcc. Du siehst mich verblüfft.

Naja, im ersten set_u Falle darf er es ja nicht wegwerfen.

Und der zweite Fall führt zu interessanten Fragestellungen bei Code wie
1
int sat_mul (int a, int b)
2
{
3
   int c = a * b;
4
5
   if (overflow)
6
      ...
7
}

zwar kann man auf einen doppelt so breiten Typen ausweichen für die 
Berechnung, aber irgendwann ist Ende der Fahnenstange — sei es weil es 
keinen beiteren Datentyp mehr gibt oder weil die Schmerzgrenze erreicht 
ist wie bei AVR + long long.

Wie macht man also eine C-konforme, halbwegs effiziente Prüfung auf 
Überlauf, z.B. bei Multiplikation wie im Beispiel?

von Michael K. (mmike)


Lesenswert?

Siehe auch hier, was "mein" Informatiker dazu gemeint hat:

http://www.fefe.de/intof.html

Grüße,
Michael

von A.R.Biter (Gast)


Lesenswert?

heute noch mal vorbeigeschaut -

- und siehe da, wie vorausgesagt, 9 hilfsbereite und
sachkundige Beiträge seit der letzten Reaktion des Thread-
Erstellers, aber nach seiner ersten Antwort war mir (leider
nur unbestimmt gefühlsmäßig) klar:
Der will keine Hilfe, zur Selbsthilfe!

Man sollte mal ein Tutorial erstellen, mit dem Thema:

Wie erkennt man möglichst schnell, bei welchen Fragestellern
lohnt es sich nicht, zu antworten?

Ist doch doof, dass

(1) Ein Haufen liebevoll eingesetzter Energie verpufft.

(2) Themen immer wieder nach oben poppen, die niemanden
    zu neuen Erkenntnissen führen.

(Außer psychologischen Erfahrungen - dafür geht aber keiner
in dieses Forum.)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.