Frage

Was passiert eigentlich, wenn ein Byte überläuft?

Sagen wir, das haben wir

byte byte1 = 150; // 10010110  
byte byte2 = 199; // 11000111

Wenn wir jetzt diese Ergänzung machen

byte byte3 = byte1 + byte2;

Ich denke, am Ende haben wir Byte3 = 94, aber was passiert eigentlich?Habe ich irgendwie einen anderen Speicher überschrieben oder ist das völlig harmlos?

War es hilfreich?

Lösung

Es ist ganz einfach. Es tut nur das Hinzufügen und kommt in einer Reihe mit mehr als 8 Bit aus. Das neunte Bit (die eine) nur ‚abfällt‘ und Sie werden mit den verbleibenden 8 Bits nach links, die die Zahl 94 bilden.

(Ja, es ist harmlos)

Andere Tipps

In C #, wenn Sie

 checked { byte byte3 = byte1 + byte2; }

Es wird ein Überlauf Ausnahme auslösen. Code ist unchecked standardmäßig erstellt. Wie die anderen Antworten sagen, wird der Wert ‚Wrap-around‘. dh byte3 = (byte1 + byte2) & 0xFF;

Die oberen Bits werden abgeschnitten. Es ist nicht schädlich auf andere Speicher, es in Bezug auf die unbeabsichtigten Ergebnissen nur schädlich ist.

Der Carry-Flag wird Satz ... aber neben dem Ergebnis nicht was es bedeutet, Sie erwarten, sollte es keine negativen Auswirkungen sein.

Normalerweise (und das genaue Verhalten von der Sprache und Plattform abhängen wird), wird das Ergebnis Modulo-256 entnommen werden. d.h. 150 + 199 = 349. 349 mod 256 = 93.

Dies sollte keine anderen Speicher beeinflussen.

Da Sie Ihre Frage C #, C ++ und C markiert haben, werde ich über C und C ++ beantworten. In c ++ Überlauf auf unterzeichnet Typen, einschließlich sbyte (was, glaube ich, ist signed char in C / C ++) führt zu undefiniertem Verhalten. Jedoch für unsigned Typen wie byte (was unsigned char in C ++) das Ergebnis ist, nimmt modulo 2 n , wobei n die Anzahl der Bits in dem unsigned Typ. In C # hält die zweite Regel, und die signierten Typen erzeugen eine Ausnahme, wenn sie in checked Block sind. Ich kann in dem C # Teil falsch sein.

Überlauf ist harmlos in c # - Sie werden nicht Überlaufspeicher - Sie einfach obly die letzten 8 Bits des Ergebnisses erhalten. Wenn Sie diese auf diese eine Ausnahme, verwenden Sie die ‚geprüft‘ Schlüsselwort. Beachten Sie, dass Sie auch int Byte + Byte gibt finden können, so dass Sie Guss zurück zu Byte benötigen.

Das Verhalten hängt von der Sprache.

In C und C ++, signiert Überlauf nicht definiert ist und ohne Vorzeichen Überlauf hat das Verhalten, das Sie erwähnt (obwohl es keine byte Typ ist).

In C # können Sie die checked Schlüsselwort explizit verwenden sagen Sie eine Ausnahme erhalten möchten, wenn es Überlauf ist und die unchecked Schlüsselwort explizit sagen Sie, es ignorieren wollen.

Führende Bit gerade abgesetzt.

Und arithmetischer Überlauf auftritt. Da 150 + 199 = 349, binär 0101 1101 1 wird die obere 1 Bit fallen gelassen und das Byte wird zu 0101 1101; das heißt die Anzahl der Bits kann ein Byte überschwemmt halten.

Es wurde kein Schaden - z.B. die Speicher habe nicht über an einem anderen Ort.

Schauen wir uns an, was tatsächlich passiert (in C (vorausgesetzt, Sie haben den entsprechenden Datentyp, da einige darauf hingewiesen haben, dass C keinen „Byte“-Datentyp hat;dennoch gibt es 8-Bit-Datentypen, die hinzugefügt werden können)).Wenn diese Bytes auf dem Stapel deklariert sind, sind sie im Hauptspeicher vorhanden.Irgendwann werden die Bytes für den Betrieb auf den Prozessor kopiert (ich überspringe einige wichtige Schritte, wie z. B. Prozessor oder Cache ...).Sobald sie im Prozessor sind, werden sie in Registern gespeichert;Der Prozessor führt eine Additionsoperation für diese beiden Register aus, um die Daten zu addieren. Hier liegt der Grund für die Verwirrung. Die CPU führt den Additionsvorgang im nativen (oder manchmal auch im angegebenen) Datentyp aus.Nehmen wir an, der native Typ der CPU ist ein 32-Bit-Wort (und dieser Datentyp wird für die Additionsoperation verwendet).das bedeutet, dass diese Bytes in 32-Bit-Worten gespeichert werden, wobei die oberen 24 Bits nicht gesetzt sind;Die Additionsoperation führt tatsächlich zum Überlauf im 32-Bit-Zielwort.Aber (und hier ist das wichtige Bit) wenn die Daten vom Register auf den Stapel zurückkopiert werden, werden nur die niedrigsten 8 Bits (das Byte) zurück an die Position der Zielvariablen auf dem Stapel kopiert.(Beachten Sie, dass auch hier eine gewisse Komplexität mit dem Packen von Bytes und dem Stapel verbunden ist.)

Also, hier ist das Ergebnis;das Hinzufügen verursacht einen Überlauf (abhängig von der spezifischen ausgewählten Prozessoranweisung);Die Daten werden jedoch aus dem Prozessor in einen Datentyp der entsprechenden Größe kopiert, sodass der Überlauf unsichtbar ist (und harmlos, einen ordnungsgemäß geschriebenen Compiler vorausgesetzt).

Soweit C # geht, um zwei Werte vom Typ byte zusammen ergibt einen Wert von Typ int die dann gegossen zurück zu byte sein muss.

Daher Code Probe ohne Guss zurück zu Byte in einem Compiler-Fehlern führen wird, wie im Folgenden.

byte byte1 = 150; // 10010110  
byte byte2 = 199; // 11000111

byte byte3 = (byte)(byte1 + byte2);

Siehe MSDN, um weitere Informationen zu diesem Thema. Siehe auch die C # Sprachspezifikation , Abschnitt 7.3.6 Numerische Aktionen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top