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?
@ 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
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_tfoo=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
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.
> Diese Information muss doch irgendwo hinterlegt sein.
Ja, und zwar in dem Programm das wo Dein Compiler (ggf. auf dem
Hostsystem) erzeugt hat :-)
HTH
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
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.
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
charc;
2
3
voidset_u(unsignedcharx)
4
{
5
if(x<100)
6
c=0;
7
}
8
9
voidset_s(signedcharx)
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:
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...
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
intsat_mul(inta,intb)
2
{
3
intc=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?
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.)