Char to unsigned int
-
huhu,
#include <iostream> using namespace std; int main() { /* Wertebereich von signed char: -128 bis 127 -->Laut ASCII Tabelle hat 'ü' den Wert 129. --> Überlauf um 2, und du landest bei -127 Wenn du nun -127 in ein signed int speicherst, hast du halt was negatives. */ signed char c = 129; // Überlauf um 2 int i = c; // i = -127 cin.get(); return 0; }Wieso du -97 hast verstehe ich grad irgendwie nicht

gruß
-
Ppp schrieb:
kann mir von euch vllt einer erklähren warum bitte ich bei der Konvertierung von einem char zu unsigned int einen negativen Wert bekomme?????
int i = (unsigned int) c; std::cout << i << " " << c << std::endl;In meinem char c steht ein ü. Als Ausgabe bekomme ich:
-97 ü
Als Compiler benutze ich den GCC CPP Compiler.
Wie bitte kann unsigned einen negativen Wert liefern?!?!?!Du rufst undefiniertes Verhalten hervor. Wenn das Verhalten nicht definiert ist, kann das, was da rauskommt, auch nicht falsch sein. Das Problem ist hier, dass der uint-Wert, der da rauskommt, nicht in ein int passt.
vorzeichenbehaftet -> vorzeichenlos ist unproblematisch. Der Wert der rauskommt ist gleich dem Original modulo 2^N, wobei N die Zahl der Bits des Zieltyps ist. -97 nach unsigned int wird also 2^32-97, falls int 32 bit hat.
vorzeichenlos -> vorzeichenbehaftet ist nur dann erlaubt, falls der Wert auch darstellbar ist. Wenn nicht --> undefiniertes Verhalten. In den meisten Fällen wird das Bitmuster einfach neuinterpretiert und Du bekommst wieder eine negative Zahl in deinem Fall.
Das, was Du machen wolltest, muss so aussehen:
char c = ...; int i = static_cast<unsigned int>(c) & 0xFF;(angenommen, dass Du CHAR_BIT==8 erwartest)
-
Dweb schrieb:
#include <iostream> using namespace std; int main() { /* Wertebereich von signed char: -128 bis 127Falsch. Der Wertebereich umfasst mindestens -127...127, möglicherweise aber auch mehr.
Dweb schrieb:
-->Laut ASCII Tabelle hat 'ü' den Wert 129. --> Überlauf um 2, und du landest bei -127Eine solche Zuweisung liefert undefiniertes Verhalten
-
krümelkacker schrieb:
vorzeichenbehaftet -> vorzeichenlos ist unproblematisch. Der Wert der rauskommt ist gleich dem Original modulo 2^N, wobei N die Zahl der Bits des Zieltyps ist. -97 nach unsigned int wird also 2^32-97, falls int 32 bit hat.
vorzeichenlos -> vorzeichenbehaftet ist nur dann erlaubt, falls der Wert auch darstellbar ist. Wenn nicht --> undefiniertes Verhalten. In den meisten Fällen wird das Bitmuster einfach neuinterpretiert und Du bekommst wieder eine negative Zahl in deinem Fall.
Das, was Du machen wolltest, muss so aussehen:
char c = ...; int i = static_cast<unsigned int>(c) & 0xFF;(angenommen, dass Du CHAR_BIT==8 erwartest)
ok, das wusst ich nicht. Wieder was gelernt :xmas1:
-
Warum nicht
unsigned int i = static_cast<unsigned char>(c); //hier kommt ein positiver Wert von 0 bis 255 rausoder
int i = c; //hier kommt ein Wert von -128 bis 127 raus@krümelkracker: Warum sollte -128 nicht möglich sein?
Ist eine dieser Varianten undefiniert?
-
wxSkip schrieb:
Warum nicht
unsigned int i = static_cast<unsigned char>(c); //hier kommt ein positiver Wert von 0 bis 255 rausoder
int i = c; //hier kommt ein Wert von -128 bis 127 raus@krümelkracker: Warum sollte -128 nicht möglich sein?
Ist eine dieser Varianten undefiniert?
Er hat nicht gesagt, dass -128 nicht möglich ist, sondern dass nur -127 bis 127 garantiet werden. Alles andere ist implementationsabhängig [-128,127], [-127,128].
Übrigens ist es auch implementationsabhängig, ob char als unsigned char oder signed char behandelt wird.
-
wxSkip schrieb:
Warum nicht
unsigned int i = static_cast<unsigned char>(c); //hier kommt ein positiver Wert von 0 bis 255 raus...kannste machen...
wxSkip schrieb:
oder
int i = c; //hier kommt ein Wert von -128 bis 127 rausNicht unbedingt. Ob char vorzeichenbehaftet ist oder nicht, ist nicht festgelegt. Du weißt, dass "signed char" und "char" zwei verschiedene Typen sind, ja?
wxSkip schrieb:
@krümelkracker: Warum sollte -128 nicht möglich sein?
Siehe C bzw C++ Standard. Er erlaubt neben dem Zweierkomplement auch andere Zahlendarstellungen wie das Einerkomplement oder die Vorzeichen-Betrag-Darstellung.
wxSkip schrieb:
Ist eine dieser Varianten undefiniert?
Das zweite könnte u.U. undefiniertes Verhalten hervorrufen -- nämlich wenn INT_MAX < CHAR_MAX gilt. Das ist zwar weit hergeholt, aber durchaus möglich.
-
krümelkacker schrieb:
wxSkip schrieb:
Ist eine dieser Varianten undefiniert?
Das zweite könnte u.U. undefiniertes Verhalten hervorrufen -- nämlich wenn INT_MAX < CHAR_MAX gilt. Das ist zwar weit hergeholt, aber durchaus möglich.
Wie das? Der Datentyp int belegt mindestens soviel Speicher wie der Datentyp char und genug um jeden Wert des Intervalls [INT_MIN, INT_MAX] aufnehmen zu können. Dann kann CHAR_MAX nicht grösser sein als INT_MAX.
Nachtrag: Vergiss die Frage - würde prinzipiell natürlich gehen.
INT_MIN = -127
INT_MAX = 127CHAR_MIN = 0
CHAR_MAX = 255
-
inter2k3 schrieb:
krümelkacker schrieb:
Das zweite könnte u.U. undefiniertes Verhalten hervorrufen -- nämlich wenn INT_MAX < CHAR_MAX gilt. Das ist zwar weit hergeholt, aber durchaus möglich.
Wie das? Der Datentyp int belegt mindestens soviel Speicher wie der Datentyp char und genug um jeden Wert des Intervalls [INT_MIN, INT_MAX] aufnehmen zu können. Dann kann CHAR_MAX nicht grösser sein als INT_MAX.
Nachtrag: Vergiss die Frage - würde prinzipiell natürlich gehen.
INT_MIN = -127
INT_MAX = 127CHAR_MIN = 0
CHAR_MAX = 255So in etwa, nur dass int mindestens 16 bit breit ist. Ich habe da an
INT_MIN = -32768
INT_MAX = 32767
CHAR_MIN = 0
CHAR_MAX = 65535
gedacht. Ob es so etwas aber wirklich gibt, weiß ich nicht. Möglich wär es aber (und standardkonform).
-
krümelkacker schrieb:
wxSkip schrieb:
oder
int i = c; //hier kommt ein Wert von -128 bis 127 rausNicht unbedingt. Ob char vorzeichenbehaftet ist oder nicht, ist nicht festgelegt. Du weißt, dass "signed char" und "char" zwei verschiedene Typen sind, ja?
Ja, habe ich aber dabei wohl "übersehen"
.