Warum oder wie klappt ein vergleich zwischen signed und unsigned int?



  • Hi,

    Warum funktioniert der Vergleich zwischen einem signed und einem unsigned int?
    Dafür müsste ja einer der beiden Paramter in den Typen der anderen
    umgewandelt werden.

    Bsp:

    unsigned long int U = std::numeric_limits< unsigned long int >::max();
    signed long int S = std::numeric_limits< signed long int >::min();
    
    if( U > S )
    {
        ;
    }
    

    Beide Zahlen haben jetzt einen Wert den der andere nicht annehmen kann,
    da dieser außerhalb dessen Bereiches liegt.

    Wie funktioniert nun der Vergleich?



  • Der signed Typ wird nach unsigned gewandelt, wenn ein unsigned Typ beteiligt ist.

    Ist im C++ Standard unter 5 /9 - "usual arithmetic conversions" beschrieben.



  • Beide Zahlen haben jetzt einen Wert den der andere nicht annehmen kann,
    da dieser außerhalb dessen Bereiches liegt.

    ist nich IMMER der Fall, solange für die Zahlen das erste Bit keine rolle spielt bzw. die zahlen so klein gehalten werden damit das erste bit nich verwendet wird^^



  • Ich habe mir jetzt die "usual arithmetic conversions" angeschaut,
    aber meine Frage konnte ich mir immer noch nicht beantworten.
    Ich weiß jetzt, in was convertiert wird, aber meiner Meinung nach
    ist dies nicht möglich, da die Zahlen verschiedene Bereiche haben.

    Nochmal mein Beispiel:

    unsigned long int U = std::numeric_limits< unsigned long int >::max();
    signed long int S = std::numeric_limits< signed long int >::min();
    
    if( U > S )
    {
        ;
    }
    

    Ich habe es kompiliert und der Vergleich stimmt, aber ich kann es mir nicht erklären.



  • Wenn der signed long nicht in unsigned long abbildbar ist weil negativ, ist das Ergebnis "implementation defined" - aus dem einfachen Grund, dass der Standard keine binäre Repräsentation vorschreibt. Bei 2er-Komplement-Darstellung sollte dir aber klar sein, was passiert, oder?

    Nachlesen kannst du das im Standard unter 4.7 "Integral conversions".


  • Mod

    7H3 N4C3R schrieb:

    Wenn der signed long nicht in unsigned long abbildbar ist weil negativ, ist das Ergebnis "implementation defined" - aus dem einfachen Grund, dass der Standard keine binäre Repräsentation vorschreibt. Bei 2er-Komplement-Darstellung sollte dir aber klar sein, was passiert, oder?

    Nachlesen kannst du das im Standard unter 4.7 "Integral conversions".

    3.9.1/7 Satz 3 sowie
    4.7/2 und 3.9.1/4 lesen.

    Das Ergebnis ist nur insoweit von der Implementation abhängig, wie der ursprüngliche vorzeichenbehaftete Wert es ist. Bzgl. des Ergebnisses der Umwandlung hat die Implementation keinen Spielraum.



  • Du arbeitest nicht zufällig für das Standardisierungskomitee oder bist als Kind in einen Standard-Kessel gefallen? 😃 Ich finde es immer wieder erstaunlich, wie du solche kleinen (aber wichtigen) Details mal so aus dem Hut zauberst. 👍

    Ich war mir auch noch nicht bewusst, dass unsigned Arithmetik per Definition nicht überlaufen kann, bzw. das Ergebnis trotzdem immer definiert ist.



  • Vielen Dank 🙂



  • Eine Frage habe ich noch.

    Bei den "Usual arithmetic Conversions" ist nie von dem
    long long int die Rede. Bei einem Vergleich zwischen long int
    und long long int, wird doch beides in einen long long int gecastet, oder?
    Im std steht davon nämlich nichts.



  • Es gibt kein long long int in C++, das gibts (bisher) nur in C99.


Anmelden zum Antworten