Forum: Mikrocontroller und Digitale Elektronik C: Größtmögliche Zahl von uint8_t


von Simon (Gast)


Lesenswert?

Hallo,

mir ist bekannt, dass in C die größtmögliche Zahl eines uint8_t 255 ist. 
Wenn ich nun eine Abfrage wie folgt mache.
1
if(--a == 255) a = 100;

ist das soweit richtig, aber gerade bei größeren Zahlen hat man die 
Max-Werte nicht umbedingt im Kopf.

Gibt es aus der stdint eine Textergänzung/Define, die immer den höchsten 
Wert beinhaltet?

von Peter II (Gast)


Lesenswert?

Simon schrieb:
> Gibt es aus der stdint eine Textergänzung/Define, die immer den höchsten
> Wert beinhaltet?

schau doch einfach mal rein in die Header Dateien.

oder einfach mal den ersten Google treffer?

http://www.cplusplus.com/reference/cstdint/

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Simon schrieb:
> Wenn ich nun eine Abfrage wie folgt mache.
Dann zählst du übrigens wider Erwarten 101 Schritte...

> gerade bei größeren Zahlen hat man die Max-Werte nicht umbedingt im
> Kopf.
Du kannst dir die paar für die tägliche Arbeit nötigen Werte doch 
einfach merken. Oder noch einfacher: in hex-Notation schreiben.

: Bearbeitet durch Moderator
von Jemand (Gast)


Lesenswert?

Die Hex-Notation verwenden halte ich für eine gute Idee. Es erfordert 
kein größes Denken und die Intention, den maximalen Wert zu haben, wird 
auch deutlich. (mache ich selbst bei chars)

von Thomas H. (Firma: CIA) (apostel13)


Lesenswert?

Jemand schrieb:
> Es erfordert
> kein größes Denken

Denken kommt eh aus der Mode...

von Daniel A. (daniel-a)


Lesenswert?

Den Maximalwert als Konstante zu Verwenden kann man meistens vermeiden. 
Das obere Beispiel kann auch folgendermassen geschrieben werden:
1
if(!a--) a = 100;
Oder so:
1
if(a-1>a) a = 100;
2
a -= 1;

von Klaus (Gast)


Lesenswert?

limits.h

von #define (Gast)


Lesenswert?

#define MAX_UINT8     0xFF     // 255

von Mark B. (markbrandis)


Lesenswert?

#define schrieb:
> #define MAX_UINT8     0xFF     // 255

Sollte man nicht selbst definieren brauchen, wenn man eine vernünftige C 
Standardbibliothek hat. Da gibt es nämlich bereits UCHAR_MAX.

von Wolfgang (Gast)


Lesenswert?

Mark B. schrieb:
> #define schrieb:
>> #define MAX_UINT8     0xFF     // 255
>
> Sollte man nicht selbst definieren brauchen, wenn man eine vernünftige C
> Standardbibliothek hat. Da gibt es nämlich bereits UCHAR_MAX.

Stimmt, Denken kommt aus der Mode.
Man muss nur die richtige Bibliothek haben.

von Daniel A. (daniel-a)


Lesenswert?

Mark B. schrieb:
> #define schrieb:
>> #define MAX_UINT8     0xFF     // 255
>
> Sollte man nicht selbst definieren brauchen, wenn man eine vernünftige C
> Standardbibliothek hat. Da gibt es nämlich bereits UCHAR_MAX.

Wenn ich folgender Seite glauben darf:
http://www.cplusplus.com/reference/cstdint/
gibt es auch ein UINT8_MAX.

Ich habe bei meinem oberen Code einen flüchtigkeitsfehler gemacht, ich 
meinte statt
1
if(a-1>a) a = 100;
natürlich folgendes:
1
if((uint8_t)(a-1)>a) a = 100;

von Cyblord -. (cyblord)


Lesenswert?

Daniel A. schrieb:
> gibt es auch ein UINT8_MAX.

Gibt es. Und das sollte man auch verwenden. Ein UCHAR_MAX bringt da 
wenig wenn man UINT8_t als Typ verwenden will. Nur weil es hier zufällig 
gleich groß ist.
Für alle (U)INTx_t Datentypen gibt es ein define für MAX und für die 
vorzeichenbehafteten auch ein MIN.

von 6a66 (Gast)


Lesenswert?

Simon schrieb:
> Hallo,
>
> mir ist bekannt, dass in C die größtmögliche Zahl eines uint8_t 255 ist.
> Wenn ich nun eine Abfrage wie folgt mache.
> if(--a == 255) a = 100;

Aaalso - wenn ich nicht irre:

a) bei einem uint8_t würde ich stillschweigend von 255 ausgehen 
ansonsten wäre die Bezeichnung irreführend. Wenn ich dann feststellen 
würde dass das nicht 255 wären würde ich den Krmepel über Bord werfen 
denn wenn bei solch grundlegenden Definitionen schon gepfuscht wird ...

b) Die Bedingung --a == 255 ist schon reichlich merkwürdig. Welche Zahl 
aus dem Zahlenraum [0;255] kann - prädekremetiert - 255 ergeben? Das 
kann logischerweise nur ein Wraparound von 0 sein. Da würde ich aber 
dann stark dran zweifeln wenn ein Programmierer die Bedingung so 
unleserlich aufsetzen würde.

rgds

von Cyblord -. (cyblord)


Lesenswert?

6a66 schrieb:
> Simon schrieb:
>> Hallo,
>>
>> mir ist bekannt, dass in C die größtmögliche Zahl eines uint8_t 255 ist.
>> Wenn ich nun eine Abfrage wie folgt mache.
>> if(--a == 255) a = 100;
>
> Aaalso - wenn ich nicht irre:
>
> a) bei einem uint8_t würde ich stillschweigend von 255 ausgehen
> ansonsten wäre die Bezeichnung irreführend.

Darum geht's nicht. Der Sinn der bitgenauen Datentypen liegt ja gerade 
darin, dass ich die Anzahl der Bits sicher angeben kann. Kenne ich die 
Bitanzahl kenne ich auch den MAX Wert. So weit so trivial.
Aber die Verwendung der MAX-Makros verbessert die Leserlichkeit, weil 
man hier nicht einfach eine Zahl im Code sieht (was man sowieso 
vermeiden sollte) sondern direkt sieht, hier wird absichtlich die größte 
/ kleinste mögliche Zahl hergenommen.

von Mark B. (markbrandis)


Lesenswert?

Daniel A. schrieb:
> Wenn ich folgender Seite glauben darf:
> http://www.cplusplus.com/reference/cstdint/
> gibt es auch ein UINT8_MAX.

Äh ja, richtig. Das sollte man nehmen.

Das kommt davon wenn man beim Posten noch nicht richtig wach ist ;-)

von 6a66 (Gast)


Lesenswert?

Cyblord -. schrieb:
> Darum geht's nicht. Der Sinn der bitgenauen Datentypen liegt ja gerade
> darin, dass ich die Anzahl der Bits sicher angeben kann. Kenne ich die
> Bitanzahl kenne ich auch den MAX Wert. So weit so trivial.

Richtig, das meinte ich.

Cyblord -. schrieb:
> Aber die Verwendung der MAX-Makros verbessert die Leserlichkeit, weil
> man hier nicht einfach eine Zahl im Code sieht (was man sowieso
> vermeiden sollte) sondern direkt sieht, hier wird absichtlich die größte
> / kleinste mögliche Zahl hergenommen.

ACK! Das habe ich aus der ursprünglichen Fragestellung aber so nicht 
rausgelesen - wenn das der Ansatz war: gut, habe ich daneben geschossen 
:(

rgds

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Mark B. schrieb:
> #define schrieb:
>> #define MAX_UINT8     0xFF     // 255
>
> Sollte man nicht selbst definieren brauchen, wenn man eine vernünftige C
> Standardbibliothek hat. Da gibt es nämlich bereits UCHAR_MAX.

Es handelt sich nicht um einen unsigned char sondern um einen uint8_t.

UINT8_MAX ist Teil von C99 und wird definiert in stdint.h.

: Bearbeitet durch User
von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

Wolfgang schrieb:
>> Sollte man nicht selbst definieren brauchen, wenn man eine vernünftige C
>> Standardbibliothek hat. Da gibt es nämlich bereits UCHAR_MAX.
>
> Stimmt, Denken kommt aus der Mode.
> Man muss nur die richtige Bibliothek haben.

Die Verwendung von Bibliotheken hat relativ wenig damit zu tun, nicht 
denken zu wollen. Wenn man eine Lösung aus einer Standard-Bibliothek 
verwendet, dann kann man auch annehmen, dass die meisten Kollegen, diese 
Lösung verstehen / kennen und dass in der Lösung deutlich weniger Fehler 
enthalten sind, als in einer eigenen Lösung.

Das setzt natürlich voraus, dass man sich regelmäßig mit den zur 
Verfügung stehenden Werkzeugen auseinander setzt.

von Joachim B. (jar)


Lesenswert?

Simon schrieb:
> ist das soweit richtig, aber gerade bei größeren Zahlen hat man die
> Max-Werte nicht umbedingt im Kopf.

ja und muss ich doch nicht

Simon schrieb:
> if(--a == 255)

würde bei
uint8_t if(--a == 0xFF)
uint16_t if(--a == 0xFFFF)
uint32_t if(--a == 0xFFFFFFFF)
uint64_t if(--a == 0xFFFFFFFFFFFFFFFF)

alternativ den #PRE rechnen lassen
uint8_t if(  --a == ((2^8)-1)  )
uint16_t if( --a == ((2^16)-1) )
uint32_t if( --a == ((2^32)-1) )
uint64_t if( --a == ((2^64)-1) )

von Cyblord -. (cyblord)


Lesenswert?

Joachim B. schrieb:
> Simon schrieb:
>> ist das soweit richtig, aber gerade bei größeren Zahlen hat man die
>> Max-Werte nicht umbedingt im Kopf.
>
> ja und muss ich doch nicht
>
> Simon schrieb:
>> if(--a == 255)
>
> würde bei
> uint8_t if(--a == 0xFF)
> uint16_t if(--a == 0xFFFF)
> uint32_t if(--a == 0xFFFFFFFF)
> uint64_t if(--a == 0xFFFFFFFFFFFFFFFF)
>
> alternativ den #PRE rechnen lassen
> uint8_t if(  --a == ((2^8)-1)  )
> uint16_t if( --a == ((2^16)-1) )
> uint32_t if( --a == ((2^32)-1) )
> uint64_t if( --a == ((2^64)-1) )

So und jetzt bitte noch (inkl. MIN) für die signed typen. Aber aus dem 
Kopf ohne Google ;-)

Aber im Ernst, diese Variante ist einfach umständlich und schwer 
leserlich.

von Joachim B. (jar)


Lesenswert?

Cyblord -. schrieb:
> Aber im Ernst, diese Variante ist einfach umständlich und schwer
> leserlich.
(hast du da Leseschwierigkeiten?)
mag sein, ist aber eine gültige Antwort die mehr hilft als

Cyblord -. schrieb:
> So und jetzt bitte noch (inkl. MIN) für die signed typen. Aber aus dem
> Kopf ohne Google ;-)

:-)

: Bearbeitet durch User
von Paul B. (paul_baumann)


Lesenswert?

Verstehe ich das richtig: Die Größe von Datentypen ist nicht einheitlich 
definiert und jeder kann das "Fassungsvermögen" des jeweiligen Typs für 
sich selbst nach Gutdünken definieren?

Das fände ich seltsam...

MfG Paul

von Cyblord -. (cyblord)


Lesenswert?

Joachim B. schrieb:
> Cyblord -. schrieb:
>> Aber im Ernst, diese Variante ist einfach umständlich und schwer
>> leserlich.
> (hast du da Leseschwierigkeiten?)
> mag sein, ist aber eine gültige Antwort die mehr hilft als

Nein, auf leserlichen Code hinzuweisen hilft immer. Deiner ist es nicht.
Außerdem ist die Methode fehleranfällig. Bei einer 32 Bit Zahl ist 
schnell mal ein F vergessen. Und den Fehler suchst du dann ewig und drei 
Tage. Ein fertiges Makro aus der Standard lib löst alle diese Probleme 
im Handstreich.

> Verstehe ich das richtig
Verstehst du falsch. Bleib bei deinen Anekdoten. Fachlich wird das nix 
mehr.

: Bearbeitet durch User
von Paul B. (paul_baumann)


Lesenswert?

Cyblord -. schrieb:
> Verstehst du falsch.
Danke für die ausführliche und wohl begründetet Antwort.
>Bleib bei deinen Anekdoten. Fachlich wird das nix
> mehr.

Ja, da hast Du Recht -mit "C" wird das bei mir nichts mehr. Muß aber 
auch nicht... Es gibt genügend Alternativen.

MfG Paul

von Cyblord -. (cyblord)


Lesenswert?

Paul B. schrieb:
> Cyblord -. schrieb:
>> Verstehst du falsch.
> Danke für die ausführliche und wohl begründetet Antwort.

Falls deine Frage ernsthaftes Interesse bekundet werde ich natürlich 
gerne Licht in die ewige Finsternis der C-Verächter bringen. Das 
gebietet allein schon meine menschenfreundliche Art.

Also:
Datentypen wie int, Long usw. sind in C nicht einheitlich definiert was 
die Bitbreite angeht. So ist int meist die native Datenbreite, 
mindestens aber 16 Bit. Auf einer 32Bit Maschine daher 32, auf 64 Bit 
eben 64. Manchmal will man aber Variablen mit Bitbreiten. Darum gibt es 
Makros mit den exakten Bitbreiten (int16_t, uint8_t usw.). Diese werden 
dann auf die entsprechenden nativen Datentypen des jeweiligen Systems 
gemappt.

von Daniel A. (daniel-a)


Lesenswert?

Joachim B. schrieb:
> alternativ den #PRE rechnen lassen
> uint8_t if(  --a == ((2^8)-1)  )

Soweit ich weiss kann der Preprozessor nicht rechnen, und das "^" steht 
für xor. es wäre eher ((1<<8)-1).

 Man kann sich auch ein eigenes macro für belibige Datentypen schreiben:
1
#define TYPE_MAX(T) ( (T)~0 > 0 ? (T)~0 : (T)~((T)1<<(sizeof(T)*8-1)) ) 
2
#include <stdio.h>
3
int main(){
4
  printf("%d %d %lld %llu\n",TYPE_MAX(char),TYPE_MAX(unsigned char),TYPE_MAX(long long),TYPE_MAX(unsigned long long));
5
}

: Bearbeitet durch User
von Paul B. (paul_baumann)


Lesenswert?

Cyblord -. schrieb:
> Falls deine Frage ernsthaftes Interesse bekundet werde ich natürlich
> gerne Licht in die ewige Finsternis der C-Verächter bringen.

Na, da bedanke ich mich doch für die vernünftige und sachliche 
Erklärung. Das meine ich wirklich so, wie ich es sage.

> Das gebietet allein schon meine menschenfreundliche Art.

Hmm, naja...
Eine Nummer kleiner hätte für das Eigenlob auch genügt...
;-)

MfG Paul

von Peter II (Gast)


Lesenswert?

Daniel A. schrieb:
> Soweit ich weiss kann der Preprozessor nicht rechnen, und das "^" steht
> für xor. es wäre eher ((1<<8)-1).

ist doch egal ob der Preprozessor rechnen kann, der Compiler kann es.

von Joachim B. (jar)


Lesenswert?

Daniel A. schrieb:
> Soweit ich weiss kann der Preprozessor nicht rechnen, und das "^" steht
> für xor. es wäre eher ((1<<8)-1).

da hast du recht, ich war im Mathemodus (Exel),
((1<<8)-1) ist hier besser geeignet!

Peter II schrieb:
> ist doch egal ob der Preprozessor rechnen kann, der Compiler kann es.

eben, darauf wollte ich hinaus und wenn ich mich recht erinnere tun das 
die allermeisten bei Konstanten auch in jeder Art von Optimierung, wird 
ja hier immer wieder behauptet.

von Boris O. (bohnsorg) Benutzerseite


Lesenswert?

Mir ist nach mehrmaligem Lesen immer noch nicht klar, warum einer 
uint8_t schreibt und sich über den Maximalwert keine Gedanken macht, 
stattdessen ein Forum befragt. Ist keinem aufgefallen, dass mich nichts 
davon abhält, einem uint16_t auch ein UCHAR_MAX zuzuweisen? Da gibt es 
keine syntaktische Absicherung (und wer zählt schon die 
Compiler-Warnungen im umgekehrten Fall?)

Solchen Menschen rate ich, lieber mit untypisierten Sprachen zu 
arbeiten, das spart viel Wartezeit (bis sich im Forum jemand traut).

von Stefan K. (stefan64)


Lesenswert?

Es macht durchaus Sinn, z.B. UINT8_MAX auf eine uint16_t anzuwenden, 
z.B. vor einer Zuweisung einer uint16_t an ein uint8_t.

ich persönlich ziehe UINT8_MAX auch einem 255 oder 0xff vor, da damit 
deutlich wird, daß es sich um den Maximlwert und nicht um irgendeine 
Zahl, die zufällig dem Maximalwert entspricht, handelt.

Gruß, Stefan

von Mark B. (markbrandis)


Lesenswert?

Boris O. schrieb:
> Ist keinem aufgefallen, dass mich nichts davon abhält, einem uint16_t auch > ein 
UCHAR_MAX zuzuweisen?

Kann man machen, da es ein gültiger wert ist. Ist halt nicht unbedingt 
guter Programmierstil. Von fragwürdigem Programmierstil hält einen 
keiner ab, erst recht nicht der C-Compiler.

Man kann übrigens auch einem uint8_t eine Konstante zuweisen, die größer 
ist als das was in uint8_t hineinpasst. Wird zwar eine Warnung geben, 
aber akzeptiert wird es.

: Bearbeitet durch User
von Mike (Gast)


Lesenswert?

Paul B. schrieb:
> Verstehe ich das richtig: Die Größe von Datentypen ist nicht einheitlich
> definiert und jeder kann das "Fassungsvermögen" des jeweiligen Typs für
> sich selbst nach Gutdünken definieren?

Zumindest bei int bzw. uint hast du IMHO aber leider Recht. Da legt der 
Compiler- bzw. Prozessorhersteller fest, welches der "natürliche" 
Ganzzahltyp ist.

von Joachim B. (jar)


Lesenswert?

Mark B. schrieb:
> Wird zwar eine Warnung geben,
> aber akzeptiert wird es.

Compilerwarnungen finde erst mal gut und schalte sie wo ich kann ein.

Es gibt aber auch Warnungen gerade im char Sektor die nerven nur, weil 
es mal signed mal unsigned char gibt, ich frage mich dann immer wieder 
wieso char mit dem Atribut signed oder unsigned geführt wird oder ob 
char nicht bei 127 enden müsste ascii oder ob char bis 255 gehen dürfen?
Aber getch ist wohl immer 16-bittig, muss am DOS liegen, jedenfalls 
nichts ist verwirrender als char, ich weiss das ein char ein Zeichen ist 
und ein Zeichen 8-bit hat, aber das war es auch schon, deswegen ist mir 
die neuere Schreibweise uint8_t auch sympatisch, aber nicht auf 
Stringroutinen anwendbar.

von Daniel A. (daniel-a)


Lesenswert?

Joachim B. schrieb:
> ich weiss das ein char ein Zeichen ist
> und ein Zeichen 8-bit hat, aber das war es auch schon, deswegen ist mir
> die neuere Schreibweise uint8_t auch sympatisch, aber nicht auf
> Stringroutinen anwendbar.

Ob ein Zeichen aus 8 bit besteht und ein char ein ganzes Zeichen 
räpresentiert ist von der Codierung abhängig, und wieviele bit der char 
Datentyp hat ist von der CPU abhängig und steht in der variable 
CHAR_BIT, welche in limits.h definiert ist.

von Dirk B. (dirkb2)


Lesenswert?

Joachim B. schrieb:
> Aber getch ist wohl immer 16-bittig, muss am DOS liegen,

Das liegt daran, dass auch noch EOF codiert werden muss.

Joachim B. schrieb:
> jedenfalls
> nichts ist verwirrender als char,

Es gibt drei Typen von char:
char ist für Zeichen (und Strings) da.
signed char für Integer mit Vorzeichen und kleinem Wertebereich
unsigned char für Integer ohne Vorzeichen und kleinem Wertebereich

von M. K. (sylaina)


Lesenswert?

Dirk B. schrieb:
> Es gibt drei Typen von char:
> char ist für Zeichen (und Strings) da.
> signed char für Integer mit Vorzeichen und kleinem Wertebereich
> unsigned char für Integer ohne Vorzeichen und kleinem Wertebereich

Autsch, da würde ich noch mal drüber nachdenken.

von Dussel (Gast)


Lesenswert?

Michael K. schrieb:
> Autsch, da würde ich noch mal drüber nachdenken.
So benutze ich es aber auch, wenn der Speicher knapp ist. Da sowohl 
char, signed und unsigned genau definiert sind, sollte das meines 
Wissens keine Probleme geben, wenn man weiß, was man macht.

von Joachim B. (jar)


Lesenswert?

Dussel schrieb:
> Da sowohl
> char, signed und unsigned genau definiert sind,

sind falsche Annahmen, bezogen auf char und signed oder unsigned, nicht 
der erste gemachte Fehler?

: Bearbeitet durch User
von Dussel (Gast)


Lesenswert?

Joachim B. schrieb:
> sind falsche Annahmen, bezogen auf char und signed oder unsigned, nicht
> der erste gemachte Fehler?
Wie meinst du das? Soweit ich weiß, hat ein char immer acht Bit, 
unsigned ist die normale Binärdarstellung und signed die Darstellung im 
Zweierkomplement. Ich denke, dass das so im Standard definiert ist, aber 
auch wenn nicht, sollte das für weit über 90% der Fälle passen.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Dussel schrieb:
> Soweit ich weiß, hat ein char immer acht Bit

Nein.  Es hat nur mindestens acht Bit, und es ist definiert, dass
es sich dabei um die kleinste adressierbare Einheit hat.

Es spricht aus Sicht des Standards jedoch nichts dagegen, dass ein
char bspw. 32 Bit hat.  Allerdings kann es auf so einer Architektur
dann kein uint8_t geben (jedoch uint_least8_t sowie uint_fast8_t).

von Dussel (Gast)


Lesenswert?

Jörg W. schrieb:
> Es hat nur mindestens acht Bit, und es ist definiert, dass
> es sich dabei um die kleinste adressierbare Einheit hat.
"…handelt"?
Interessant, das wusste ich nicht. Dann bleibt aber noch der zweite Teil 
meiner Aussage. Gibt es in nennenswertem Umfang Systeme, bei denen ein 
char mehr als acht Bit hat? XCode gibt auf meinem x64 ein Byte als Größe 
eines chars aus.

von Mark B. (markbrandis)


Lesenswert?

Dussel schrieb:
> Interessant, das wusste ich nicht. Dann bleibt aber noch der zweite Teil
> meiner Aussage. Gibt es in nennenswertem Umfang Systeme, bei denen ein
> char mehr als acht Bit hat? XCode gibt auf meinem x64 ein Byte als Größe
> eines chars aus.

Die PDPs hatten teilweise ulkige Wortbreiten. Aber die benutzt wohl 
heute niemand mehr - außer als Staubfänger im Museum ;o)

https://en.wikipedia.org/wiki/Programmed_Data_Processor

Ansonsten siehe stackoverflow.com:

http://stackoverflow.com/questions/2098149/what-platforms-have-something-other-than-8-bit-char

: Bearbeitet durch User
von Klaus (Gast)


Lesenswert?

Oh. Richtig. Library-Types in stdint.h und nicht limits.h. Sorry.

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.