unsigned char negieren



  • Hallo,
    ich habe in meinem Code etwa sowas:

    unsigned char a = 20;
    std::cout << (static_cast<int>(a) ^ 0x80000000) << std::endl;
    

    Damit möchte ich die Variable a negieren. Allerdings wird trotz dem static_cast<int> die Variable als unsigned interpretiert und statt -20 liefert mit cout 2147483668.
    Wie kann ich das Problem lösen?





  • int ^ uint = uint. Wenn du den zweiten Typ zu int castest, erhälst du ein negatives Ergebnis, allerdings nicht -20, was du vielleicht erwarten würdest. Wenn du -20 mit XOR erreichen willst, musst du beim Zweierkomplement schon Folgendes machen:

    unsigned char a = 20;
    std::cout << (static_cast<int>(a) ^ static_cast<int>(0xFFFFFFFF)) + 1 << std::endl;
    


  • "unsigned" steht für vorzeichenlos, da ist negieren ein wenig witzlos. Und in deinem Beispiel kommt noch die integral promotion (0x80000000 ist zu groß um int zu sein, also wird auf unsigned int umgeschaltet) und die Zweierkomplement-Darstellung (x ^ 0x80000000 ist was anderes als -x) dazwischen.
    Wenn du unbedingt den negierten Wert deines unsigned char ausgeben willst, mußt du ihn erst in einen vorzeichenbehafteten Typ casten und dann negieren - also -static_cast<int>(a) .



  • Pikkolini schrieb:

    unsigned char a = 20;
    std::cout << (static_cast<int>(a) ^ 0x80000000) << std::endl;
    

    Damit möchte ich die Variable a negieren. Allerdings wird trotz dem static_cast<int> die Variable als unsigned interpretiert und statt -20 liefert mit cout 2147483668.

    Beschäftige Dich mit
    - integral promotion c++
    - usual arithmetic conversions c++
    - integer literals c++
    (und/oder siehe C++ Buch Deiner Wahl)

    Auf einem 32Bit-System ist durchaus zu erwarten, dass 0x8000000 vom Typ "unsigned int" ist. Dann hättest Du "signed int ^ unsigned int" wobei für den ersten Operand eine der "usual arithmetic conversions" durchgeführt wird, welche die linke Seite wieder vorzeichenlos macht. Der ganze Ausdruck ist damit vorzeichenlos und vom Typ "unsigned int".

    Schreibst Du stattdessen einfach -a findet eine integral promotion statt (unsigned char -> signed int (1)) und der int-Wert wird wegen des unären Minusoperators negiert.

    (1: Der Zieltyp ist "unsigned int", falls "signed int" den Wertebereich von "unsigned char" nicht komplett abdeckt. UCHR_MAX > INT_MAX ist aber unwahrscheinlich)

    kk


Anmelden zum Antworten