Angenommen, ich habe die Nummer 'numb'=1025 [00000000 00000000 00000100 00000001]
dargestellt:
Auf Little-Endian-Maschine:
00000001 00000100 00000000 00000000
Auf Big-Endian-Maschine:
00000000 00000000 00000100 00000001
Wenn ich nun Left Shift auf 10 Bits anwende (dh: numb << = 10), sollte ich Folgendes haben:
[A] Auf Little-Endian-Maschine:
Wie ich in GDB bemerkt habe, macht Little Endian die Linksverschiebung in 3 Schritten: [Ich habe '3' Schritte gezeigt, um nur die Verarbeitung besser zu verstehen]
Behandle die Nr. in der Big-Endian-Konvention:
00000000 00000000 00000100 00000001
Linksverschiebung anwenden:
00000000 00010000 00000100 00000000
Stellen Sie das Ergebnis erneut in Little-Endian dar:
00000000 00000100 00010000 00000000
[B]. Auf Big-Endian-Maschine:
00000000 00010000 00000100 00000000
Meine Frage ist:
Wenn ich direkt eine Linksverschiebung auf die Little Endian Convention anwende, sollte sie Folgendes ergeben:
numb
::
00000001 00000100 00000000 00000000
numb << 10
::
00010000 00000000 00000000 00000000
Aber eigentlich gibt es:
00000000 00000100 00010000 00000000
Um nur das zweite Ergebnis zu erzielen, habe ich oben drei hypothetische Schritte gezeigt.
Bitte erklären Sie mir, warum die beiden oben genannten Ergebnisse unterschiedlich sind: Das tatsächliche Ergebnis von numb << 10
unterscheidet sich vom erwarteten Ergebnis.
quelle
Nein, Bitshift wird wie jeder andere Teil von C als Wert und nicht als Repräsentation definiert. Linksverschiebung um 1 ist Multiplikation um 2, Rechtsverschiebung ist Division. (Achten Sie wie immer bei der Verwendung von bitweisen Operationen auf die Signatur. Bei vorzeichenlosen Integraltypen ist alles am besten definiert.)
quelle
x &= -1u << 20
sie höchstwahrscheinlich falsch, wenn siex
64-Bit undint
32-Bit ist. Aus diesem Grund verspricht GCC, unterschriebene Schichten niemals als undefiniert oder gar nicht spezifiziert zu behandeln.Welcher Verschiebungsbefehl zuerst die höherwertigen Bits herausschiebt, wird als Linksverschiebung betrachtet. Welcher Verschiebungsbefehl zuerst die Bits niedrigerer Ordnung herausschiebt, wird als die richtige Verschiebung angesehen. In diesem Sinne hängt das Verhalten von
>>
und<<
fürunsigned
Zahlen nicht von der Endianness ab.quelle
Computer schreiben Zahlen nicht so auf wie wir. Der Wert verschiebt sich einfach. Wenn Sie darauf bestehen, es Byte für Byte zu betrachten (obwohl der Computer dies nicht so macht), können Sie sagen, dass auf einer Little-Endian-Maschine das erste Byte nach links verschoben wird und die überschüssigen Bits in das zweite Byte gehen. und so weiter.
(Übrigens ist Little-Endian sinnvoller, wenn Sie die Bytes eher vertikal als horizontal mit höheren Adressen oben schreiben. So werden Speicherzuordnungsdiagramme üblicherweise gezeichnet.)
quelle
Die akzeptierte Antwort weist jedoch darauf hin, dass Endianess ein Konzept aus der Sicht des Gedächtnisses ist. Aber ich denke nicht, dass das die Frage direkt beantwortet.
Einige Antworten sagen mir, dass bitweise Operationen nicht von der Endianess abhängen und der Prozessor die Bytes auf andere Weise darstellen kann. Wie auch immer, es geht darum, dass Endianess abstrahiert wird.
Aber wenn wir zum Beispiel einige bitweise Berechnungen auf dem Papier durchführen, müssen Sie dann nicht zuerst die Endianess angeben? Meistens wählen wir implizit eine Endianess.
Angenommen, wir haben eine solche Codezeile
0x1F & 0xEF
Wie würden Sie das Ergebnis von Hand auf Papier berechnen?
Hier verwenden wir also ein Big Endian-Format, um die Berechnung durchzuführen. Sie können auch Little Endian verwenden, um das gleiche Ergebnis zu berechnen und zu erhalten.
Übrigens, wenn wir Zahlen in Code schreiben, denke ich, dass es wie ein Big Endian-Format ist.
123456
oder die0x1F
meisten signifikanten Zahlen beginnen von links.Sobald wir ein Binärformat eines Wertes auf das Papier schreiben, haben wir wahrscheinlich bereits eine Endianess ausgewählt und sehen den Wert so, wie wir ihn aus dem Speicher sehen.
Zurück zur Frage: Eine Verschiebungsoperation
<<
sollte als Verschiebung von LSB (niedrigstwertiges Byte) zu MSB (höchstwertiges Byte) betrachtet werden .Dann wie für das Beispiel in der Frage:
numb=1025
Kleiner Endian
LSB 00000001 00000100 00000000 00000000 MSB
So
<< 10
würde10bit
Verschiebung von LSB zu MSB.Vergleich und
<< 10
Operationen für das Little Endian-Format Schritt für Schritt:Beeindruckend! Ich bekomme das erwartete Ergebnis wie im OP beschrieben!
Die Probleme, bei denen das OP nicht das erwartete Ergebnis erzielt hat, sind folgende:
Es scheint, dass er nicht von LSB zu MSB gewechselt ist.
Wenn Sie Bits im Little Endian-Format verschieben, sollten Sie Folgendes beachten (Gott sei Dank, ich erkenne es):
LSB 10000000 00000000 MSB << 1
istLSB 00000000 00000001 MSB
, nichtLSB 01000000 00000000 MSB
Denn für jeden Einzelnen
8bits
schreiben wir es tatsächlich in einemMSB 00000000 LSB
Big Endian-Format.So ist es wie
LSB[ (MSB 10000000 LSB) (MSB 00000000 LSB) ]MSB
Um zusammenzufassen:
Obwohl bitweise Operationen blablablabla weg abstrahiert werden sollen ... müssen wir bei der Berechnung bitweiser Operationen von Hand immer noch wissen, welche Endianess wir verwenden, wenn wir das Binärformat auf das Papier schreiben. Außerdem müssen wir sicherstellen, dass alle Operatoren dieselbe Endianess verwenden.
Das OP hat nicht das erwartete Ergebnis erzielt, weil er die Schaltung falsch gemacht hat.
quelle