Anfängerfrage -> Falsche Eingaben abfangen



  • Hallo zusammen 🙂

    Ich bin gerade bei Kalistos Buch "C++ für Spieleprogrammierer".

    In einem Kapitel war es Aufgabe einen Countdown zu programmieren.

    Dieser sollte nach erreichen der Hälfte dieses auch anzeigen.

    So weit so gut... ich habe das auch gelöst... glaub ich jedenfalls da die gewünschten Bedingungen erfüllt worden.

    Beim testen bin ich jedoch auf ein Problem gestoßen welches mich irritiert...

    Ich musste damit die Hälfte erkannt wird mit Modulo arbeiten um ungerade Zahlen auszuschließen. Klappte auch...

    Aber wenn ich zb. -10 eingab hat der Countdown bei vermutlich 65535 gestartet..
    Ich vermute das ist ein Überlauf ? den ich zwar nicht verstehe aber das ist nicht der Grund warum ich hier gerade schreibe...

    Vielmehr interessiert es mich wie kann ich jetzt bei der Prüfung der Eingabe prüfen ob diese signed ist und das abfangen, oder den Wertebereich vorgeben...
    Hatte unsigned short als Zählvariable für den Countdown. Aber man könnte ja auch größere Zahlen eingeben oder Zahlen mit - vielleicht ja auch Text .... die würden ja trotzdem in irgendeiner Form durchlaufen....

    Andererseits hab ich gerade Angst dass man später nur noch damit beschäftigt ist Falscheingaben jeglicher Form abzufangen und man dadurch den Code nur noch komplexer und dadurch ja auch anfälliger zu machen....

    So alla : if (i<Wertebereich && i!=TEXT && i!=Vorzeichen && i!=USW ) ....
    sowas ließe sich ja noch weiter fortsetzen.... oder gibt es später für Fortgeschrittene bessere Lösungen ?

    Denn wenn man nur nach dem gehen müsste was die Aufgabenstellung verlangt könnte man viele Sachen doch bestimmt viel einfacher gestalten 😉



  • Whitedragon276 schrieb:

    Hallo zusammen 🙂
    Vielmehr interessiert es mich wie kann ich jetzt bei der Prüfung der Eingabe prüfen ob diese signed ist und das abfangen, oder den Wertebereich vorgeben...
    Hatte unsigned short als Zählvariable für den Countdown. Aber man könnte ja auch größere Zahlen eingeben oder Zahlen mit - vielleicht ja auch Text .... die würden ja trotzdem in irgendeiner Form durchlaufen....

    Denn wenn man nur nach dem gehen müsste was die Aufgabenstellung verlangt könnte man viele Sachen doch bestimmt viel einfacher gestalten 😉

    mach es doch einfach so? 😕

    if (eingabe > 0)
    

    was willst du daran noch vereinfachen? 🙄



  • sry hatte ich vergessen...

    du solltest auch mögliche fehleingaben abfangen, sonst funktioniert dein programm ja unter umständen nicht richtig...

    ich seh es so, es gibt immer einen der einen buchstaben tippt wenn da steht "zahl eingeben".
    entweder weil er im stress nicht richtig gelesen oder eine böse absicht hat, usw.

    hoff ich konnte helfen
    lg



  • Hier mal der QC dazu :

    #include <iostream> 
    
    using namespace std;
    
    int main()
    {
        cout << "Countdown" << endl;
        cout << "\n" << "\n" << "\n" << endl;
        cout << "Bitte eine gew\201nschte gerade ! Startzahl eingeben" << endl;
        cout << "\n\n\n" << endl;
    
    //  cout << "\255" << endl;
    
    int startzahl;
    cin >> startzahl;
    
    [b]if ( startzahl%2==0 )[/b]
     {
        cout << "Sie haben eingegeben : " << startzahl << endl;
    
        cout << "\n\n\nNun also der Countdown" << endl;
        cout << "\n\n\n" << endl;
    
        for (int i=startzahl; i>=0;i--)
    
            if (i==(startzahl/2) )
            cout << i <<" \tHalbzeit" << "\n" << endl;
    
            else
            cout << i << "\n" << endl;
     }
    
    else cout << "Sie haben leider eine falsche Zahl eingegeben \001 !\n\n\n" << endl;
    
    return 0;
    }
    

    Bräuchte das Fehlerabfangen ja in dieser Zeile :

    if ( startzahl%2==0 )

    und wenn ich hier dann : if ( ( startzahl%2==0 )&&( startzahl>0 ) )schreibe, dann bekomme ich erst mal wieder Fehlermeldungen,
    weil ich wohl dabei was falsch mache.
    Und selbst wenn ich die dann weg habe,
    sagt das ausgeführte Programm bei mir
    wenn ich -10 eingebe das selbe wie vorher....

    Das könnte aber auch an meinem "noch" nicht ausgereiftem Verständnis der logischen Operatoren liegen...

    Ausserdem wird die ganze Sache dadurch nicht wirklich verständlicher....

    Und Danke noch mal für die Antwort 🙂



  • was für fehlermeldungen bekommst du denn da?

    übrigens: die modulo-operation benutzt du jetzt genau wofür? wenn ich 5423 eingebe, ist 2711 doch genau genug, oder nicht? bzw. wenns wirklich genau sein soll, kommst du um richtige zeitmessung doch gar nicht herum. 🙄



  • Da du von irgendetwas herunterzählst sollte der Wert auch immer vorzeichenlos sein (also keine negativen Werte). Also statt int besser unsigned int für die Eingabe benutzen. Du musst in der for Schleife beachten, dass du dann auf > 0 prüfen musst.



  • Whitedragon276 schrieb:

    Hier mal der QC dazu :
    Bräuchte das Fehlerabfangen ja in dieser Zeile :

    if ( startzahl%2==0 )

    warum nicht?

    if (startzahl>0)
    {
      if(startzahl%2==0)
      {
        //mach i.was
      }
    }
    

    oder:

    if ((startzahl>0) and (startzahl%2==0))
    

    (so wird übrigens auch zuerst überprüft ob die zahlt größer 0 ist)

    Whitedragon276 schrieb:

    und wenn ich hier dann : if ( ( startzahl%2==0 )&&( startzahl>0 ) )schreibe, dann bekomme ich erst mal wieder Fehlermeldungen,
    weil ich wohl dabei was falsch mache.
    Und selbst wenn ich die dann weg habe,
    sagt das ausgeführte Programm bei mir
    wenn ich -10 eingebe das selbe wie vorher....

    Das könnte aber auch an meinem "noch" nicht ausgereiftem Verständnis der logischen Operatoren liegen...

    Ausserdem wird die ganze Sache dadurch nicht wirklich verständlicher....

    Und Danke noch mal für die Antwort 🙂

    du hast ja in deinem code auch kein if(eingabe>0)?
    du musst den code schon einfügen...

    wenn du die fehler nicht abfängst bzw. behandelst ist dein programm fehlerhaft und funktioniert erst gar nicht richtig?
    da es ja nicht das tut was du erwartest bzw. wolltest.

    was soll da "verständlicher" werden ...
    dein programm bricht undefiniert ab, sehr unverständlich wie ich finde bzw. sogar einfach falsch.

    unübersichtlich wird das durch (startzahl > 0) ja nun auch nicht das sind 2 oder jenachdem wie man es betrachtet 3 worte.

    wenn es darum geht solltest du lieber nochmal grundlagen der ausgabe mit cout wiederholen, denn es ist klar erkennbar das dir dort wissen fehlt.

    vll hilft auch eine ordentliche formatierung für dich die übersichtlichkeit zu wahren.
    schau mal, ich habe dein code mal etwas überarbeitet.

    übrigens ein std::endl beinhaltet ein "\n" also beides hinter einander ist wenig sinnvoll. 🙄

    #include <iostream>
    
    using namespace std;
    
    int main()
    {
        cout << "Countdown \n\n\n" << "Bitte gerade zahl eingeben: \n";
    
    	int startzahl;
    	cin >> startzahl;
    
    	if ((startzahl>0) and (startzahl%2==0))
    	{
    		cout << "Sie haben eingegeben : \n" << startzahl << "\n";
    
    		for (int i=startzahl; i>=0; i--)
    		{
    			if (i == (startzahl/2))
    			{
    				cout << "Halbzeit: " << i << endl;
    			}
    			else
    			{
    				cout << "aktuell bearbeite Zahl: " << i << endl;
    			}
    		}
    	}
    	else
    	{
    		cout << "Sie haben leider eine kleinere als 0 oder ungerade Zahl eingegeben - dies ist nicht möglich!" << endl;
    	}
    
    	return 0;
    }
    

    bei mir funktionieren alle prüfungen also ich kann keine ungeraden zahlen und keine kleineren als 0 eingaben ohne das die fehlermeldung erscheint.

    theoretisch musst du noch prüfen ob die "länge" der eingegeben zahl auch wirklich in eine int variable passt, aber gehen wir jetzt einfach mal davon aus das das schon passt.

    hoff ich konnte helfen
    lg



  • HansKlaus schrieb:

    was für fehlermeldungen bekommst du denn da?

    übrigens: die modulo-operation benutzt du jetzt genau wofür? wenn ich 5423 eingebe, ist 2711 doch genau genug, oder nicht? bzw. wenns wirklich genau sein soll, kommst du um richtige zeitmessung doch gar nicht herum. 🙄

    Die Fehlermeldungen müsste ich nachschauen wenn ich wieder zu Hause bin 😉

    Die Modulo benutz ich hier nur, weil das die Vorgabe der Aufgabe war und nur ganze Zahlen als Ergebnis zugelassen waren 🙂

    Und ich hoffe dass ich das so verstanden habe in meinem Ausdruck dass wenn Modulo 0 ist -> ich keinen Rest habe und daher eine ganze Zahl habe.

    Weiter bin ich leider noch nicht ..... 😉

    DocShoe schrieb:

    Da du von irgendetwas herunterzählst sollte der Wert auch immer vorzeichenlos sein (also keine negativen Werte). Also statt int besser unsigned int für die Eingabe benutzen. Du musst in der for Schleife beachten, dass du dann auf > 0 prüfen musst.

    Zu Hause hatte ich das auch bereits in unsigned short geändert... allerdings im Text noch nicht 😉
    trotzdem hat er den Countdown gestartet wenn ich -10 eingab, statt in die else zu gehen...

    Wobei das ja auch immer noch 2 Byte sind also 0-65535, was für einen normalen Countdown auch "etwas" viel ist .)
    Gibts hier für Anfänger keine Alternative ? Char dürfte nicht gehen nehm ich mal an... und eigenen Datentyp definieren .... äh ja... später 😃

    Oder darf ich diese Überlegungen gerne auf später verlegen und erst mal weiter im Stoff machen -> der Rest kommt später ja bestimmt noch ...

    In der for Schleife meinst Du damit : for (int i=startzahl; i>=0; i--)
    oder soll innerhalb der for Schleife noch mal mit if geprüft werden ?

    Werde da wohl noch mal etwas hin & her schieben.... vielleicht klappt es ja 🙂

    ----------------------------------------------------------------------

    Dabei fällt mir grade noch was ein. Wenn ich cout benutze und zb. \n sind das ja glaube ich Steuerzeichen....
    ich kann mit dem \ aber auch andere Symbole / Buchstaben / Zahlen ausgeben....

    sind die auf allen Systemen gleich oder ändern die sich ?

    Mein Problem hier ist ich kann ja mit cout nicht zb << ändern schreiben da er das ä nicht kennt...
    also mache ich zu Hause \203 für ä... scheint aber nicht auf jedem PC zum selben Ergebnis zu führen....

    in der ASCII Tabelle gibts die ä,ö & ü ´s auch nicht.... die Werte 1-127 sind anscheinend fix und die von 128-255 kann ich nicht über die for Schleife mit dem Char++ nicht abfragen weil die nicht mehr funktioniert sobald ich über 127 komme....
    Hilft hier nur durchprobieren ? oder kann ich das irgendwo nachlesen ?
    Aber unter dem Suchbegriff ASCII Tabelle oder Steuerzeichen hab ich nichts gefunden.... 😕 😕 😕

    @Wertz Super, Danke ja das hilft mir schon weiter .... und ja ich brauche definitiv mehr Übung.... bisher hab ich viel gelesen wenig probiert.... da ist wohl schon das Hauptproblem.... viele Dinge hab ich so wie die verschachtelten if´s auch noch gar nicht im Hinterkopf...



  • Whitedragon276 schrieb:

    trotzdem hat er den Countdown gestartet wenn ich -10 eingab, statt in die else zu gehen...

    Wobei das ja auch immer noch 2 Byte sind also 0-65535, was für einen normalen Countdown auch "etwas" viel ist .)
    Gibts hier für Anfänger keine Alternative ? Char dürfte nicht gehen nehm ich mal an... und eigenen Datentyp definieren .... äh ja... später 😃

    ich vermute jetzt mal, dass die -10 einfach als entsprechender unsigned-wert interpretiert wird.
    sei doch einfach mal ein bisschen gleichgültig und benutz für so einzelne sachen pauschal int, in zeiten wo 4GB arbeitsspeicher relativ wenig sind, fällt das eher nicht so auf. 😃

    Oder darf ich diese Überlegungen gerne auf später verlegen und erst mal weiter im Stoff machen -> der Rest kommt später ja bestimmt noch ...

    das schöne an "erwachsenenbildung" ist, dass man machen kann, was man will. bill gates hat immer ein grottenschlechtes betriebssystem zusammengezimmert und ist trotzdem reich geworden. halte dich nicht so sehr an kleinigkeiten auf.

    in der ASCII Tabelle gibts die ä,ö & ü ´s auch nicht.... die Werte 1-127 sind anscheinend fix und die von 128-255 kann ich nicht über die for Schleife mit dem Char++ nicht abfragen weil die nicht mehr funktioniert sobald ich über 127 komme....

    keine ahnung wie das jetzt genau abläuft, aber ich weiß, dass printf diese zeichen darstellen kann - oder du nimmst unicode (besser weil genormt und damit überall gleich).



  • Danke für die vielen Tipps 🙂

    Ich hoffe ich werde auch lernen diese zu beherzigen 🙂



  • Whitedragon276 schrieb:

    Mein Problem hier ist ich kann ja mit cout nicht zb << ändern schreiben da er das ä nicht kennt...
    also mache ich zu Hause \203 für ä... scheint aber nicht auf jedem PC zum selben Ergebnis zu führen....

    in der ASCII Tabelle gibts die ä,ö & ü ´s auch nicht.... die Werte 1-127 sind anscheinend fix und die von 128-255 kann ich nicht über die for Schleife mit dem Char++ nicht abfragen weil die nicht mehr funktioniert sobald ich über 127 komme....
    Hilft hier nur durchprobieren ? oder kann ich das irgendwo nachlesen ?
    Aber unter dem Suchbegriff ASCII Tabelle oder Steuerzeichen hab ich nichts gefunden.... 😕 😕 😕

    @Wertz Super, Danke ja das hilft mir schon weiter .... und ja ich brauche definitiv mehr Übung.... bisher hab ich viel gelesen wenig probiert.... da ist wohl schon das Hauptproblem.... viele Dinge hab ich so wie die verschachtelten if´s auch noch gar nicht im Hinterkopf...

    schau mal wegen den umlauten in der konsole:
    https://www.c-plusplus.net/forum/viewtopic.php?t=39326

    das sollte helfen... 🙄

    lg



  • #include <iostream>
    
    using namespace std;
    
    int main()
    {
        cout << "Countdown \n\n\n" << "Bitte gerade zahl eingeben: \n";
    
    	int startzahl;
    	cin >> startzahl;
    
    	if ((startzahl>0) and (startzahl%2==0))
    	{
    		cout << "Sie haben eingegeben : \n" << startzahl << "\n";
    
    		for (int i=startzahl; i>=0; i--)
    		{
    			if (i == (startzahl/2))
    			{
    				cout << "Halbzeit: " << i << endl;
    			}
    			else
    			{
    				cout << "aktuell bearbeite Zahl: " << i << endl;
    			}
    		}
    	}
    	else
    	{
    		cout << "Sie haben leider eine kleinere als 0 oder ungerade Zahl eingegeben - dies ist nicht möglich!" << endl;
    	}
    
    	return 0;
    }
    

    bei mir funktionieren alle prüfungen also ich kann keine ungeraden zahlen und keine kleineren als 0 eingaben ohne das die fehlermeldung erscheint.

    theoretisch musst du noch prüfen ob die "länge" der eingegeben zahl auch wirklich in eine int variable passt, aber gehen wir jetzt einfach mal davon aus das das schon passt.

    hoff ich konnte helfen
    lg[/quote]

    Funktioniert tadellos , Danke !

    Habe meinen eigenen Code daraufhin auch etwas umgebaut und habe jetzt dieses hier :

    #include <iostream>
    
    using namespace std;
    
    int main()
    
    {
    
        cout << "Countdown" << endl;
    
        cout << "Bitte eine gew\201nschte gerade Startzahl eingeben \n" << endl;
    
    unsigned short startzahl;
    
    cin >> startzahl;
    
    if ((startzahl>0) && (startzahl%2==0))
    
     {
    
        cout << "Sie haben eingegeben : " << startzahl << endl;
    
        cout << "\n\nHier also der Countdown" << endl;
    
        for (int i=startzahl; i>=0;i--)
    
            if (i==(startzahl/2) )
            {
              cout << "\t" << i <<" \tSie haben die H\204lfte erreicht" << endl;
            }
                 else
                 {
                 cout << "\t" << i  << endl;
                 }
    
     }
    
    else cout << "Sie haben leider eine falsche Zahl eingegeben \001 !\n\n\n" << endl;
    
        return 0;
    
    }
    

    Habe aber immer noch das selbe Problem... bei allen Eingaben die ungerade oder Buchstaben sind geht es auch... bei allen Zahlen mit Minus die gerade sind macht er das bei mir immer noch.... Wenn ich mir nun Deinen Code ansehe fällt mir natürlich sofort die übersichtliche Formatierung auf... und genau hier scheint auch mein Problem zu liegen.... da werde ich definitiv noch üben üben üben müssen.... dieses Verschachteln scheint mir nicht ganz ohne.... aber das bekomme ich schon noch hin , Danke jedenfalls für Deine Mühe 🙂

    [quote="UMLAUT"]

    Whitedragon276 schrieb:

    schau mal wegen den umlauten in der konsole:
    https://www.c-plusplus.net/forum/viewtopic.php?t=39326

    das sollte helfen... 🙄

    lg

    genau das ist es !!! Vielen vielen Dank ! 👍



  • Whitedragon276 schrieb:

    bei allen Zahlen mit Minus die gerade sind macht er das bei mir immer noch....

    du verwendest ja auch unsigned short. weiß nicht, ob dir "zweierkomplement" etwas sagt, aber abhängig von signed oder unsigned wird das so oder anders interpretiert und aus der -100 wird plötzlich eine 65436, die logischer weise größer 0 ist.



  • Für die Umlautproblematik stellt Windows:
    https://msdn.microsoft.com/en-us/library/windows/desktop/dd319646(v=vs.85).aspx
    zur Verfügung, bzw., wenn man Konsoleneingaben entgegennimmt und dann lesbar in eine Datei schreiben will, also für den umgekehrten Fall:
    https://msdn.microsoft.com/en-us/library/windows/desktop/ms647494(v=vs.85).aspx



  • Unter Windows kannst Du durch Einsatz geeigneter Funktionen dafür sorgen, dass unerwünschte Zeichen (Buchstaben, Minuszeichen, Leerzeichen usw.) gar nicht erst akzeptiert werden, ein schnell hingeklöppeltes Beispiel:

    #include <windows.h>
    #include <iostream>
    
    using namespace std;
    
    int getInput()
    {
        INPUT_RECORD ir;
    
        DWORD dummy;
        do
        {
            ReadConsoleInput(GetStdHandle(STD_INPUT_HANDLE), &ir, 1, &dummy);
        }while(ir.EventType != KEY_EVENT || !ir.Event.KeyEvent.bKeyDown);
    
        return ir.Event.KeyEvent.uChar.AsciiChar;
    }
    
    int getPositiveInt()
    {
       //Enter-Taste definieren
       char Enter = 13;
    
       //Gültige Werte festlegen
       char werte[256] = {0};
       //Für das erste Zeichen sind nur 1 - 9 gültig
       for(int i = '1'; i <= '9'; ++i)
          werte[i] = 1;
    
       int zahl = 0;
       int zeichen;
    
       //Zeichen von der Tastatur lesen
       do
       {
          zeichen = getInput();
          if(werte[zeichen])
          {
             //Nach mindestens einer gültigen Ziffer ist auch die 0 gültig
             werte['0'] = 1;
             cout << static_cast<char>(zeichen);
             zahl = zahl * 10 + zeichen - '0';
          }
       }
       while(zeichen != Enter);
    
       return zahl;
    }
    
    int main()
    {
       cout << "Gib eine Zahl ein:\n";
       int zahl = getPositiveInt();
       cout << "\nDu hast eingegeben: " << zahl;
    
    }
    


  • HansKlaus schrieb:

    Whitedragon276 schrieb:

    bei allen Zahlen mit Minus die gerade sind macht er das bei mir immer noch....

    du verwendest ja auch unsigned short. weiß nicht, ob dir "zweierkomplement" etwas sagt, aber abhängig von signed oder unsigned wird das so oder anders interpretiert und aus der -100 wird plötzlich eine 65436, die logischer weise größer 0 ist.

    -10 fängt er bei 65436 an, -100 ebenso, -2, -1000088 usw auch

    -1, -1001, -55555555 funktioniert

    Ich gehe davon aus dass ich beim Verschachteln Mist gebaut habe... wobei ich den Code von Wertz mit meinem verglichen ( und auch die Gültigkeitsbereiche farblich markiert und verglichen habe... ) und bin der Meinung das sich bis auf die Lesbarkeit den selben Code habe. Jedenfalls kann ich keine Abweichung finden die das Problem erklären könnte...
    Bleibt ja wirklich fast nur die unsigned short über.. denn da hat Wertz ein int genommen..... muss ich noch mal testen....

    "zweierkomplement" sagt mir so nichts.... aber während ich mir das noch mal durchlese macht das vielleicht doch Sinn...Überlauf kenn ich - dürfte ähnlich sein...Gott ist das alles kompliziert...

    Danke für den Tipp! 👍



  • zweierkomplement bedeutet, dass du den betrag der zahl negierst und 1 hinzu zählst. die 10 ist also (aufgrund von faulheit am beispiel char) 0000 1010, invertiert dann 1111 0101 und mit 1 mehr 1111 0110, was dann die entsprechende -10 in zweierkomplementdarstellung ist, allerdings gleichzeitig auch die 246 als unsigned.
    probiers mal im windowstaschenrechner aus, abgesehen vom überlauf ist 10 + (-10) = 0.

    in deinem code hast du in zeile 14 unsigned short stehen, während in dem anderen code in zeile 9 int steht.



  • Whitedragon276 schrieb:

    "zweierkomplement" sagt mir so nichts.... aber während ich mir das noch mal durchlese macht das vielleicht doch Sinn...Überlauf kenn ich - dürfte ähnlich sein...Gott ist das alles kompliziert...

    Ist es nicht. Ist eigentlich ganz einfach.

    Stell dir mal naiv vor, wie du die Bitpräsentation verschiedener Werte durchführen würdest. Da würdest du ja auch erstmal das so machen:

    0000 0000 = 0
    0000 0001 = 1
    0000 0010 = 2
    0000 0011 = 3
    ...
    

    Und so weiter. So lang, wie du bei 1111 1111 (255) angekommen bist.

    Jetzt willst du da aber auch negative Werte reinpacken können. Und der negative und der positive Bereich sollen möglichst groß sein. Deswegen sagt man sich, gut, wenn das most significant bit (MSB) gesetzt ist, dann handelt es sich um eine negative Zahl, ansonsten eine positive Zahl. Das ist das Einerkomplement.

    Und das funktioniert ja auch ganz gut:

    1111 1111 = -127
    1111 1110 = -126
    ...
    1000 0010 = -2
    1000 0001 = -1
    0000 0000 = 0
    0000 0001 = 1
    0000 0010 = 2
    ....
    0111 1110 = 126
    0111 1111 = 127
    

    Wie du siehst, sind der negative und der positive Bereich gleichermaßen verteilt.
    Aber x86 verwendet das Zweierkomplement. Was ist denn das nun wieder?

    Nun, was ist 1000 0000? Die Zahl habe ich oben bewusst weggelassen, aber es handelt sich hier um eine vorzeichenbehaftete 0. Dem gegenüber steht eine vorzeichenlose 0. 0 ist aber immer 0, egal ob vorzeichenbehaftet oder nicht. Deswegen sagt man beim Zweierkomplement: gut, die vorzeichenbehaftete 0 kommt weg, an deren Stelle tritt die -1. Und alle Zahlen im negativen Bereich rücken eins auf:

    1111 1110 = -127
    1111 1101 = -126
    ...
    1000 0001 = -2
    1000 0000 = -1
    0000 0000 = 0
    

    Aber am Ende bleibt noch 1111 1111. Im Zweierkomplement gibt es dann eine Zahl im negativen Bereich, für die es keine positive Entsprechung gibt - -128, -32768, -2147483648 usw. Oder hexadezimal 0xFF, 0xFFFF, 0xFFFF FFFF usw.

    Beim Einerkomplement kriegt man also die positive/negative Zahl raus, indem man das MSB toggelt, dann trägt man -0 mit sich rum. Aber hier gibt es keine negative Zahl, die nicht auch positiv dargestellt werden kann. Beim Zweierkomplement toggelt man das MSB, und bei der Umwandlung negativ => positiv subtrahiert man 1, bei der Umwandlung positiv => negativ addiert man. Klar soweit?

    Es gibt noch andere Negativzahlendarstellungen, aber die beiden sollte jeder kennen.

    EDIT: "Kompliment" durch "Komplement" ersetzt.



  • Komplement 👍



  • dachschaden schrieb:

    Nun, was ist 1000 0000? Die Zahl habe ich oben bewusst weggelassen, aber es handelt sich hier um eine vorzeichenbehaftete 0. Dem gegenüber steht eine vorzeichenlose 0. 0 ist aber immer 0, egal ob vorzeichenbehaftet oder nicht. Deswegen sagt man beim Zweierkomplement: gut, die vorzeichenbehaftete 0 kommt weg, an deren Stelle tritt die -1. Und alle Zahlen im negativen Bereich rücken eins auf:

    1111 1110 = -127
    1111 1101 = -126
    ...
    1000 0001 = -2
    1000 0000 = -1
    0000 0000 = 0
    

    Aber am Ende bleibt noch 1111 1111. Im Zweierkomplement gibt es dann eine Zahl im negativen Bereich, für die es keine positive Entsprechung gibt - -128, -32768, -2147483648 usw. Oder hexadezimal 0xFF, 0xFFFF, 0xFFFF FFFF usw.

    Beim Einerkomplement kriegt man also die positive/negative Zahl raus, indem man das MSB toggelt, dann trägt man -0 mit sich rum. Aber hier gibt es keine negative Zahl, die nicht auch positiv dargestellt werden kann. Beim Zweierkomplement toggelt man das MSB, und bei der Umwandlung negativ => positiv subtrahiert man 1, bei der Umwandlung positiv => negativ addiert man. Klar soweit?

    Hast Du dir diesen Unsinn selbst ausgedacht oder irgendwo gelesen?

    Eine korrekte Beschreibung gibts bei Wikipedia


Anmelden zum Antworten