Verständnisfrage, unsigned/signed



  • Hey ihr,
    Also, ich hab mal ne frage, ich bin etwas verwirrt, ich habe eine funktion geschrieben, die unsigned ints als parameter übernimmt. als ich diese testen wollte, war es mir dennoch möglich z.b. -1 zu übergeben (also einen signed value). die funktion arbeiztete auch dennoch wie erwartet, also richtig 🙂 wie kommt das? und wie funktioniert das??
    sorry, wegen der eventuell heftig schlechten rechtschreibung, bin schon müde... *gähn*, danke schon mal



  • Ich hab probeweise mal folgendes ausprobiert:

    #include <iostream>
    
    using namespace std;
    
    void main()
    {
    	unsigned int test = -1;
    
    	cout << test;
    }
    

    Dabei rausgekommen ist folgende Zahl: 4294967295
    Also, ein normaler signed int geht von -2147483647 bis +2147483647 laut limits.h. Folglich bekommt ein unsigned int den negativen Bereich für den positiven Bereich sozusagen gutgeschrieben. Übersteigt ein Variablenwert dieses Limit, so fängt der Compiler an, von hinten weiterzuzählen, wie hier im Beispiel.
    Wenn deine Funktion tatsächlich das erwartete Ergebnis liefert, dann tät mich das ziemlich wundern 😃

    MFG
    #C



  • #include <iostream>
    int main () {
       std::cout << unsigned(-1) << '\n';
    }
    

    na, was wird ausgegeben?
    bei mir ist es 4294967295.
    das hängt damit zusammen, wie negative zahlen intern dargestellt werden.
    umgekehrt:

    cout << signed(4294967295) << '\n';
    

    gibt bei mir -1 aus.

    mein compiler warnt mich übrigens vor solchen fehlern 😉



  • Jo, das ist so ziemlich das selbe, was ich da oben geschrieben hab.

    Wieso warnt dein Compiler und meiner nich 😕
    Ich hab VC++6. Wo gibts eigentlich die Option, dass man ALLE Warnungen aktivieren kann, wo wir grad schon mal dabei sind?

    mfg
    #C



  • du warst eben schneller. hab deine antwort einfach noch nicht gesehen 🙂
    mein compiler ist g++. der macht sowas. wie es mit dem von ms aussieht weiß ich nicht. Irgendwo, so ich mich erinnere, gibt es aber eine Einstellung für alle Warnungen zum anklicken.
    Spiel dich herum 😉



  • Projekt -> Eigenschaften -> Warnlevel.

    Ich lass mich sogar vor sowas warnen:

    D3DCOLOR color;
    
    if (Player::humanPlayerID == Player::BLUE)
        color = 0xFF1010FF;
    else if (Player::humanPlayerID == Player::RED)
        color = 0xFFFF2020;
    else if (Player::humanPlayerID == Player::GREEN)
        color = 0xFF00AA00;
    else if (Player::humanPlayerID == Player::YELLOW)
        color = 0xFFFFFF00;
    lpSprite->Draw(unitColorTexture[Interface::buildCursorType][0], NULL, NULL, NULL, NULL, &D3DXVECTOR2(drawX, drawY), color);
    

    warning C4701: local variable 'color' may be used without having been initialized

    Ich finde es eh erstaunlich, dass man sowas überhaupt kompilieren kann...
    Selbst wenn man sicher weiß, dass color immer einen Wert kriegt, wo ist der Aufwand, das letzte else if durch else zu ersetzen?
    Dann hätte sich M$ die umfangreiche Prüfung zur Laufzeit sparen können 🙄

    Undefiniertes Verhalten ist IMO das schlimmste, was man in einem Programm anrichten kann. Und im Nachhinein am schwierigsten zu beheben.



  • Optimizer schrieb:

    Selbst wenn man sicher weiß, dass color immer einen Wert kriegt, wo ist der Aufwand, das letzte else if durch else zu ersetzen?

    D3DCOLOR color;
    
    if (Player::humanPlayerID == Player::BLUE)
        color = 0xFF1010FF;
    else if (Player::humanPlayerID == Player::RED)
        color = 0xFFFF2020;
    else if (Player::humanPlayerID == Player::GREEN)
        color = 0xFF00AA00;
    else if (Player::humanPlayerID == Player::YELLOW)
        color = 0xFFFFFF00;
    else
        assert(false);
    lpSprite->Draw(unitColorTexture[Interface::buildCursorType][0], NULL, NULL, NULL, NULL, &D3DXVECTOR2(drawX, drawY), color);
    

    finde ich da schon besser 😉



  • signed und unsigned int nutzen beide 8/ 16 / 32 / 64 Bit um ihre Zahlen darzustellen

    Somit kann ich mit 16 Bit unsigned die Zahlen 0 bis 65535 (0x0..0xFFFF) darstellen.
    Nutze ich nun signed so wird per definitionem das MSB als das Sign Bit bezeichnet.

    Ich kann als nur noch die Zahlen 0 bis 32767 (hex 0x0 ..0x7FFFF) darstellen.
    Allerdings einmal mit dem obersten Bit nicht gesetzt dann sind die Werte Positiv
    und einmal mit dem obersten Bit gestezt dann sind die Werte Negativ.
    Damit die Addition von 1 und -1 unmittelbar 0 ergibt ist -1 als 0x7FFF mit dem Sign Bit gestetzt
    als 0xFFFF definiert 0xFFFF + 0x1 = 0x0

    Damit ist die größte negative Zahl 0x80000 = -32768

    Für die anderen Zahlengrößen gilt dies analog.



  • 0000 0001 ist zwar 1 aber
    1000 0001 ist nicht -1, denn zusätzlich,w enn das sign Bit gesetzt ist, werden alle anderen Bits umgedreht.

    1111 1111 = -1
    1111 1110 = -2

    etc.



  • also, danke für die zahlreichen, umfangreichen antworten, danke
    @Zyrian ja, ich kann es mir auch nich erklären, aber die funktioin funzt tatsächlich wie erwartet/gewünscht.
    aber ich werde die funktion dann wohl besser auf signed ints umstellen, danke nochmal,
    cya



  • Mis2com schrieb:

    0000 0001 ist zwar 1 aber
    1000 0001 ist nicht -1, denn zusätzlich,w enn das sign Bit gesetzt ist, werden alle anderen Bits umgedreht.

    1111 1111 = -1
    1111 1110 = -2

    etc.

    lol? Bitsumdrehen? LOL

    0000 0001 = 1? LOOOOOOOOOOOOOOOOOOOOOOOOOL (Ist ein Smily-Zeichen)
    1000 0000 = -1? LOOOL (Ist ein C mit einem g drunter)

    Aber umdrehen? Woher haste denn den scheiss?

    Kauf dir mal ne ASCII Tabelle wo auch die Binärs, Hex, Oktal und Steuerzeichen drin stehen!




Anmelden zum Antworten