C++ Endianess



  • Abend,

    ich wollte testen, ob C++ für die Variablen Big oder Little-Endian benutzt und ob die Wahl vllt Abhängig von der Plattform ist. Ich benutzte Windows 7 + Intel CPU, also Little-Endian Plattform.
    Mit diesem Code geb ich die Binärdarstellung einer Zahl aus:

    int n = 1234567899;
    for (int i=31; i>=0; i--) {
        int bit = ((n >> i) & 1);
        cout << bit;
    }
    

    Die Ausgabe ist bei mir 01001001100101100000001011011011, sprich genauso, wie man es aufm Blatt Papier hinschreiben würde.
    Für n = 2 gibt er 00000000000000000000000000000010 aus. Heißt das jetzt, dass C++ intern IMMER Big-Endian benutzt? Ich habe eigentlich eher eine Little-Endian darstellung erwartet. Aber offenbar benutzt C++ Big-Endian, denn 2 in little Endian wäre ja 00000010 00000000 00000000 00000000, oder?



  • Endianess ist plattformabhängig.



  • biglittle schrieb:

    Aber offenbar benutzt C++ Big-Endian, denn 2 in little Endian wäre ja 00000010 00000000 00000000 00000000, oder?

    Nein. >> und & und so nehmen die Bits, wie sie logisch sind. Die können dabei physikalisch dennoch verwürfelt rumliegen.

    Mach mal

    int n = 1234567899;
    char* pch=reinterpret_cast<char*>(&n);
    cout<<int(*pch);
    


  • Bytesex hat an dieser Stelle überhaupt keine Bedeutung. i >> 1 schiebt immer das kleinste Bit raus.

    Endianness dreht sich um die Anordnung der Byte einer Zahl im Speicher. Wenn du

    #include <iostream>
    #include <tr1/cstdint>
    
    void bitprint(char c) {
      for(int i = 7; i >= 0; --i) {
        std::cout << (c >> i & 1) ? '1' : '0';
      }
    }
    
    int main() {
      union {
        std::tr1::uint32_t x;
        char b[4];
      } u;
    
      u.x = 123456789;
    
      for(int i = 0; i < 4; ++i) {
        bitprint(u.b[i]);
        std::cout << ' ';
      }
    
      std::cout << std::endl;
    }
    

    schreibst, wirst du

    00010101 11001101 01011011 00000111 <-- auf x86
    00000111 01011011 11001101 00010101 <-- auf SPARC
    

    kriegen.



  • volkard schrieb:

    Nein. >> und & und so nehmen die Bits, wie sie logisch sind. Die können dabei physikalisch dennoch verwürfelt rumliegen.

    Mach mal

    int n = 1234567899;
    char* pch=reinterpret_cast<char*>(&n);
    cout<<int(*pch);
    

    Hab den char in unsigned char geändert und dann gibt er bei mir 219 aus, binär: 11011011 (sprich das Byte ganz rechts in der Form, wie man es aufm Blatt Papier (Big-Endian) aufschreiben würde).
    Ok, das heißt es wird also Little-Endian bei mir benutzt. Auf einem Big-Endian System würde *pch also das MSB ausgeben? Was bestimmt eigentlich ob das Zeug im Big oder Little-Endian Format ist, nur das Betriebssystem oder nur die CPU? Wie würden zb Zahlen gespeichert werden wenn ich ein Big-Endian BS (zB Mac OS 😵 hab und eine Little-Endian CPU?

    Was mir noch nicht ganz klar ist: Wenn die Zahlen bei mir in Little-Endian stehen, wieso gibt dann mein Code die Zahl in Big-Endian aus? Ich arbeite doch mit den Bitoperatoren direkt auf der Zahl. 😕



  • biglittle schrieb:

    Was mir noch nicht ganz klar ist: Wenn die Zahlen bei mir in Little-Endian stehen, wieso gibt dann mein Code die Zahl in Big-Endian aus? Ich arbeite doch mit den Bitoperatoren direkt auf der Zahl. 😕

    Nein. Du arbeitest auf einem Prozessor-Register. Im register ist alles ok und sinnvoll. Nur runter ins Ram wird mit der Verdrehung geschrieben und gelesen.



  • volkard schrieb:

    Nein. >> und & und so nehmen die Bits, wie sie logisch sind. Die können dabei physikalisch dennoch verwürfelt rumliegen.

    Ich habe mich auf die Endianess bezogen, was imo auch gefragt war.
    Aber die Operatoren arbeiten natürlich wie erwartet. Sonst könnte man ja schnelle Multiplikation/Division ja nicht gescheit machen. 🙂



  • drakon schrieb:

    volkard schrieb:

    Nein. >> und & und so nehmen die Bits, wie sie logisch sind. Die können dabei physikalisch dennoch verwürfelt rumliegen.

    Ich habe mich auf die Endianess bezogen, was imo auch gefragt war.
    Aber die Operatoren arbeiten natürlich wie erwartet. Sonst könnte man ja schnelle Multiplikation/Division ja nicht gescheit machen. 🙂

    Sorry. Ich hatte Dir gar nicht widersprochen. Aber ohne Quote in meinem Posting sah es so aus. Hab's jetzt richtiggestellt.



  • biglittle schrieb:

    ...

    ich ein Big-Endian BS (zB Mac OS 😵 hab und eine Little-Endian CPU?

    Wie kommst du auf die Idee, dass OS X ein Big-Endian System sei? Auf alten PowerPC-Systemen wird Big Endian, auf Intel Little Endian verwendet.



  • volkard schrieb:

    Sorry. Ich hatte Dir gar nicht widersprochen. Aber ohne Quote in meinem Posting sah es so aus. Hab's jetzt richtiggestellt.

    Ok. Habe meinen auch noch unmissverständlich ausgedrückt. 🙂


Anmelden zum Antworten