-
        

Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 12

Thema: gemischter Vergleich mit signed und unsigned

  1. #1
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    05.11.2007
    Ort
    Berlin
    Beiträge
    526

    gemischter Vergleich mit signed und unsigned

    Anzeige

    Hallo zusammen,
    daß es ein Problem beim Vergleichen mit signed und unsigned Typen gibt ist mir inzwischen bekannt.
    Wenn ein Wert als unsigned definiert wird und der zweite als signed, wird wohl generell mit unsigned verglichen,
    so habe ich es zumindest bisher verstanden, bzw. wurde mir das hier im Forum mal so erläutert.
    Das scheint aber nicht immer so zu sein, wie mir mein Code grade zeigt. Das ist Typabhängig, zumindest bei meinem Compiler: IAR Embedded Workbench ???

    Code:
    /*----------------------------------------*/
    signed   short istWert;
    unsigned short sollWert;
    int dummy;
    
    int main(void)
    { U32 time;
     
      istWert  = -1;
      sollWert = 12;
      if (istWert < sollWert)
      {
         dummy = 1;  /* hier geht es */
      }    
    }
    /*----------------------------------------*/
    signed   int istWert;
    unsigned int sollWert;
    int dummy;
    
    int main(void)
    { U32 time;
     
      istWert  = -1;
      sollWert = 12;
      if (istWert < sollWert)
      {
         dummy = 1;  /* hier geht es NICHT !!!!! */
      }    
    }
    Anscheinend habe ich es doch noch nicht richtig verstanden ?.
    Aber zum Glück habe ich Euch...und freue mich über eine Antwort...
    Siro

  2. #2
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    Aus deinem Beitrag kann ich schließen, dass beim IAR der Typ short kleiner ist als der Typ int.

    Und jetzt überlege mal, warum ich diesen Schluss ziehen kann, denn diese Überlegung enthält dann auch die Antwort auf deine Frage.
    MfG
    Stefan

  3. #3
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    05.11.2007
    Ort
    Berlin
    Beiträge
    526
    Hallo sternst,
    also mit deiner Vermutung daß der Short kleiner ist als der Int, gebe ich Dir erstmal recht.


    Aber nun werde ich mal versuchen was mir das sagt:

    Der Short hat in meinem Falle eine Bitbreite von 16.
    Demnach bei einem "signed short " einen Wertebereich von -32768 bis+32767

    Der int hat 32 Bits also bei einem signed int -2147483648 bis +2147483647

    -1 wird in signed 16 Bit als 0xFFFF dargestellt.
    -1 mit 32 Bit ist 0xFFFFFFFF

    +12 ist in 16 Bit 0x000C
    +12 in 32 Bit ist 0x00000000C

    jetzt die Abfrage
    if (0xFFFF < 0x000C) würde FALSE ergeben, wenn ich die Werte ohne Vorzeichen behandele,
    denn 65535 ist NICHT kleiner als 12
    TRUE wenn ich die Vorzeichen beachte, weil -1 nunmal kleiner ist als +12
    Das Ergebnis des Compilers ist richtig, er liefert TRUE, hat also anscheinend das Vorzeichen richtig beachtet.
    Würde er ohne Vorzeichen arbeiten wäre das Ergebnis FALSE weil 65535 NICHT kleiner ist als 12
    Also ist das Ergenis einwandfrei bei 16 Bit Operationen.

    nun der Fall für 32 Bit
    if (0xFFFFFFFF < 0x000000C) würde FALSE ergeben, wenn ich die Werte ohne Vorzeichen behandele.
    TRUE wenn ich die Vorzeichen beachte.
    Das Ergebnis des Compilers ist aber FALSCH, er behandelt das Vorzeichen anscheinend nicht
    und deshalb ist 4294967296 nicht kleiner als 12 und damit liefert er FALSE, was halt FALSCH ist.

    Im Prinzip ist es mir eagal ob er die Mischung von signed und unsigned nicht hinbekommt, dann aber bitte konsequent
    immer falsch, aber bitte nicht Bitanzahl abhängig.

    Mir ist der Arbeitsweise hier leider nicht einleuchtend. Vielleicht denke ich immer noch zu viel in Assembler ???

    Eigentlich spielt das doch gar keine Rolle wie viele Bits ich für einen signed bzw. unsigned benutze. Dafür
    gibt es doch eine Rechenvorschrift, die hier anscheinend nicht immer identisch "verhackstückt" wird.

    Ich verstehe es wirklich nicht,
    komme nicht dahinter,
    Siro
    Geändert von Siro (30.11.2011 um 19:38 Uhr)

  4. #4
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    Im Prinzip ist es mir eagal ob er die Mischung von signed und unsigned nicht hinbekommt, dann aber bitte konsequent
    immer falsch, aber bitte nicht Bitanzahl abhängig.
    Das Ergebnis des gemischten Vergleichs ist nicht von der Bitanzahl abhängig. Der springende Punkt ist, dass bei dem Vergleich mit den short Variablen gar kein gemischter Vergleich stattfindet, sondern ein reiner signed/signed-Vergleich. Warum? int-Promotion!
    Geändert von sternst (25.11.2011 um 00:44 Uhr)
    MfG
    Stefan

  5. #5
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    05.11.2007
    Ort
    Berlin
    Beiträge
    526
    Ersteinmal guten Morgen sternst,
    wuste ich doch, daß ich mal wieder was nicht wuste

    Du hast mal wieder den Nagel auf den .....
    Das Zauberwort "Integer Promotion" habe ich noch nie gehört und google grade ein bischen.
    Habs noch nicht ganz verstanden, bin aber auf dem besten Wege dahin. Zumindest liegt da wohl die Antwort auf meine Frage.
    Das ist aber eine böse Falle, für Programmierer wie mich, mit relativ wenig Erfahrungen in der Progrmmiersprache C.
    Bedanke mich ganz herzlich.
    Siro

  6. #6
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    05.11.2007
    Ort
    Berlin
    Beiträge
    526
    So, ich hoffe, ich habe es jetzt richtig verstanden. Eine Rückmeldung wär nett, "Jo, stimmt "oder "völliger Blödsinn"

    Ich versuche mal das Problem zu beschreiben, so wie ich es jetzt verstanden habe:

    Der Compiler möchte einen Vergleich zweier Zahlen durchführen.


    30.11.2011 Siro ist schlauer geworden......
    !!!!!! was jetzt folgt ist völliger Blödsinn und ich möchte nicht, daß Ihr nur annähernd glaubt was ich hier vorher interpretiert habe.
    Ich lasse es aber der Vollständigkeit halber trotzdem stehen
    .

    signed int a;
    unsigned int b;
    if (a < b) ...



    Wir stellen ihm einen signed int 32 Bit Wert zur Verfügung „a“
    . Das ist also ein 31 Bit Wert für die Zahlendarstellung und ein zusätzliches Bit für das Vorzeichen. Dann haben wir einen unsigned Wert „b“auch 32 Bits, dieser hat aber KEIN Vorzeichen, hier werden also alle 32 Bits für die Zahlendarstellung benötigt. Damit der Compiler einen Vergleich durchführen kann, versucht er zunächst beide Werte auf die gleiche Anzahl Bits zu „erweitern“. Da also Wert „b“ 32 Bits ohne Vorzeichen hat und Wert „a“ ein Vorzeichen besitzt, benötigen wir mindestens einen Datentyp mit 33 Bits. 32 Bits für die Zahlendarstellung und ein Bit für das Vorzeichen. Das geht aber nicht, da der Datentyp „int“ in meinem Falle mit 32 Bit schon voll ausgelastet ist. Was also tun ??? Man hat sich anscheinend mal dazu entschieden, das Vorzeichen wegzulassen, damit der 32 Bit Zahlenwert in den „int“ rein passt. Das Vorzeichen wird also nun für die eigentliche Zahlendarstellung benutzt und schwups wird aus einem signed int ein unsigned int. Was natürlich Auswirkungen auf das Ergebnis hat. Der Vergleich schlägt fehl. Entscheidend ist die interne Darstellungsweise des Datentyps „int“ und dieser ist je nach verwendeten Compiler bzw. verwendeter Zielhardware unterschiedlich. Kann also 8,16,32 oder sogar 64 Bit breit sein. Also kurz gesagt, der Compiler versucht den nächst „breiteren“ (grösseren) Datentyp zu wählen in den beide Werte komplett mit Vorzeichen hineinpassen. Bei meinem Prozessor mit „int“ = 32 Bit kann er also ohne Probleme und ohne Datenverlust einen unsigned short (16 Bit) in einen signed int (32) Bit wandeln, was er aber nicht kann, ist eine 32 Bit unsigned int ohne Datenverlust in einen int mit 32 Bit plus Vorzeichenbit wandeln. Also verschwindet das Vorzeichen und der Wert wird unweigerlich als unsigned interpretiert obwohl er eigentlich signed sein sollte.


    Siro.
    Geändert von Siro (30.11.2011 um 19:39 Uhr)

  7. #7
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    Eine Rückmeldung wär nett, "Jo, stimmt "oder "völliger Blödsinn"
    Ich weiß gar nicht so recht, wo ich das jetzt einordnen soll. Das stimmt irgendwie alles so halb. Was allerdings überhaupt nicht stimmt, ist der Grund warum der Compiler aus den short für den Vergleich int macht. Mit den Vorzeichen und gemischten Vergleichen hat das nämlich nichts zu tun.
    MfG
    Stefan

  8. #8
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    05.11.2007
    Ort
    Berlin
    Beiträge
    526
    Schade eigentlich, für mich klang das sehr plausibel.
    Dann sollte ich den Text mal lieber wieder löschen, sonst glaubt das noch jemand so.
    Siro

  9. #9
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    54
    Beiträge
    5.782
    Blog-Einträge
    8
    Hallo

    Laß den Text mal besser stehen. Auch wenn's noch nicht stimmt würde der Thread durchs Löschen zu sehr zerrissen. Nettes Grundlagenthema finde ich übrigends.

    Gruß

    mic

    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  10. #10
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    Siro,
    du solltest dir wirklich mal ernsthaft Gedanken um dein grundsätzliches Vorgehen machen. Ständig probierst du nur rum und ziehst dann aus deinen Beobachtungen deine eigenen Schlüsse, wie es sein könnte. Man kann eine Programmiersprache auf die Art nicht richtig lernen. Zum einen können diese Schlüsse schlicht falsch sein (was sie ja auch schon mehrfach waren), zum anderen hat jede Sprache irgendwelche Grundregeln, die man sich fast unmöglich auf diese Art selbst "erarbeiten" kann. Und warum sollte man das auch überhaupt erst probieren, wo doch der richtige Weg nicht nur zuverlässiger, sondern auch schneller ist. In der Zeit, die du bisher mit deinen "Eigenforschungen" verbracht hast, hättest du mit Sicherheit auch locker ein C-Buch sorgfältig durcharbeiten können. "Herumprobieren" ist höchstens sinnvoll, um zu überprüfen, ob man alles richtig verstanden hat. Und wenn ich dann noch daran denke, dass es bei dir nicht um eine Freizeitbeschäftigung geht, sondern um deinen Job ....


    Zum Thema:

    '<' ist ein normaler Operator wie auch '+', '-', etc. Das bedeutet, dass für ihn auch die Integer-Promotion-Rules gelten. Im wesentlichen ist das:
    1) Die Typen der Operanden werden auf die selbe Größe gebracht. Der Größte "gibt den Takt vor", mindestens aber int.
    2) Haben die Typen bereits die selbe Größe, aber eine unterschiedliche Signedness, wird in unsigned gerechnet.

    Bei den int-Operanden sorgt 2) für das unerwartete Ergebnis.
    Bei den short-Operanden spielt 2) keine Rolle mehr, nachdem 1) angewendet wurde.
    MfG
    Stefan

Seite 1 von 2 12 LetzteLetzte

Ähnliche Themen

  1. unsigned volatile long ??
    Von Ali_Baba im Forum C - Programmierung (GCC u.a.)
    Antworten: 9
    Letzter Beitrag: 04.03.2009, 21:31
  2. Warum uint16_t statt unsigned int?
    Von ricola im Forum C - Programmierung (GCC u.a.)
    Antworten: 6
    Letzter Beitrag: 05.07.2007, 18:38
  3. Signed integer-Werte Vergleichen
    Von *Mario* im Forum PIC Controller
    Antworten: 1
    Letzter Beitrag: 21.06.2006, 12:09
  4. 16Bit unsigned integer auf AVR
    Von cumi im Forum C - Programmierung (GCC u.a.)
    Antworten: 2
    Letzter Beitrag: 13.04.2006, 21:07
  5. Signed or Unsigned
    Von Arexx-Henk im Forum C - Programmierung (GCC u.a.)
    Antworten: 4
    Letzter Beitrag: 13.02.2006, 17:05

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •