fräge zum 64 Bit Wörtern ...



  • Weiss irgendjemand ob es auf den heutigen gaengigen Systemen (32 Bit)
    moeglich ist ohne grosse Umstände 64 Bit Wörter zu verwenden!?

    Hintergrund:
    In einem Artikel ueber Schach-Programmierung ist die Rede von 64 Bit Wörtern als Darstellung für einen Figurentyp. Im zugehoerigen Source code habe ich folgende Deklaration fuer jenes Wort gefunden:

    #if defined(HAS_64BITS)
    typedef unsigned long BITBOARD;
    #elif defined(NT_i386)
    typedef unsigned __int64 BITBOARD;
    #else
    typedef unsigned long long BITBOARD;
    #endif
    

    Was soll ich darunter verstehen? (Bei mir trifft letzterer Fall zu denke ich, aber was ist denn bitte unsigned long long !?!?! Kann man sowas ueberhaupt machen?)

    Zu Kommentaren hierzu waere ich sehr dankbar.

    Grussle



  • In C++ gibt es keinen long long Typ. Der wurde erst mit C99 eingeführt, wird daher vom C++ Standard nicht berücksichtigt. Die meisten Compiler unterstützen aber trotzdem einen 64 Bit Typen. Entweder long long (also auch unter C++ als Erweiterung) oder einen Compiler spezifischen, wie zB der MSC mit __int64. Diese Typen behandelt man dann genauso wie die elementaren Ganzzahltypen, können also sowohl signed als auch unsigned sein. Unter 64 Bit Systemen ist dann idR long als 64 Bit Typ definiert, deshalb brauchst du dort nichts spezielles.
    Um jetzt in jeder Situation, egal welches System oder welcher Compiler, einen 64 Bit Typ zu haben, macht macht halt so eine bedingte Kompilierung.



  • hmm, das heisst ich braeuchte mir mit obiger anweisung bei einem gaengigen
    pc-system keine gedanken machen und einfach um ein 64 Bit Wort zu erstellen

    BITBOARD x;
    

    deklarieren, und davon ausgehen das x nun ein 64 Bit Wort ist !?!?

    Sind die gaengigen Bit-Operatoren denn nun auch fuer diese Art von Datentypen verfügbar!?

    Danke fuer die Antwort.



  • also ich habe mal das was ich gepostet habe ausprobiert:

    mein compiler schluckt das ganze zwar ganz brav, aber beispielsweise ist
    folgendes falsch:

    BITBOARD test = 1 << 32; // ergibt nicht wie erwartet eine 2^(32) !?!?!
    

    obiges ergibt eine null bei mir. anscheinend wird BITBOARD nun doch als long angenommen und die 1 ueber die 4 byte grenze hinweggeschoben.

    Ist es uerhaupt moeglich einen Datentyp zu schaffen der obiges moeglich machen wuerde!?!?

    vielen dank vorab.



  • peperony schrieb:

    Ist es uerhaupt moeglich einen Datentyp zu schaffen der obiges moeglich machen wuerde!?!?

    #ifdef _WIN64
     typedef unsigned long      ULONGLONG;
     typedef long               LONGLONG;
    #elif defined(_MSC_VER) && (_MSC_VER <= 1200) /* wenn MSVC und Version <= 6 */
     typedef unsigned __int64   ULONGLONG;
     typedef __int64            LONGLONG;
    #else
     typedef unsigned long long ULONGLONG;
     typedef long long          LONGLONG;
    #endif
    

    Sollte mit den meisten Compilern klappen (getestet mit MSVC 6.0, MSVC 7.1, BCC 5.5, BCC 5.6.4, GCC/MinGW 2.0.0, GCC/MinGW 3.5).

    Moritz



  • also entweder bin ich zu bloed oder es gibt ein missverstaendnis ...

    folgender code:

    #ifdef _WIN64
     typedef unsigned long      ULONGLONG;
     typedef long               LONGLONG;
    #elif defined(_MSC_VER) && (_MSC_VER <= 1200) /* wenn MSVC und Version <= 6 */
     typedef unsigned __int64   ULONGLONG;
     typedef __int64            LONGLONG;
    #else
     typedef unsigned long long ULONGLONG;
     typedef long long          LONGLONG;
    #endif
    
    typedef ULONGLONG BITBOARD;
    
    int main(int argc, char* argv[])
    {
       BITBOARD test  = (1 << 31);
       BITBOARD test2 = (1 << 32);
       return 0; 
    }
    

    Beim debuggen kann ich sehen dass der Werte fuer test und test2 wie folgt sind
    (hexadezimal):

    test: 0xffffffff80000000
    test2: 0x0000000000000000

    Da frage ich mich dann natuerlich wieso test2 nun den Wert null hat!?!?!?
    Ich haette da eher den Wert 2^32 erwartet.

    Den 64 bitigen Datentypen habe ich nun aber ich wollte eigentlich auch die gaengigen Bit-Operatoren auf ihm verwenden und wissen wie das gehen wuerde.

    Vielleicht habe ich auch nen Denkfehler. Ich weiss nicht genau wie das ist mit den MSB (most significant bit) und LSB (least significant bit) bei den gaengigen
    PC-Architekturen und ob das hier vielleicht ne Rolle spielt und deshalb nicht funzt!?

    Fuer Gedanken hierzu waere ich sehr dankbar.

    Grussle.



  • ok es lag doch daran dass ich zu bloed war :))

    es lag an folgendem:

    // die 1 muss gecastet werden !!!!
    __int64 test = (__int64) 0x1 << 34;
    

    trotzdem danke.



  • Ich bin nicht sicher, aber vielleicht funktioniert test2 = BITBOARD(1) << 32 ?


  • Mod

    peperony schrieb:

    ok es lag doch daran dass ich zu bloed war :))

    es lag an folgendem:

    // die 1 muss gecastet werden !!!!
    __int64 test = (__int64) 0x1 << 34;
    

    trotzdem danke.

    dafür gibt es suffixe ...

    test = 1ULL << 34;
    


  • camper schrieb:

    dafür gibt es suffixe ...

    test = 1ULL << 34;
    

    Ja, aber sizeof(1ULL) ist doch wieder Systemabhaengig!?



  • peperony schrieb:

    mein compiler schluckt das ganze zwar ganz brav, aber beispielsweise ist
    folgendes falsch:

    BITBOARD test = 1 << 32; // ergibt nicht wie erwartet eine 2^(32) !?!?!
    

    obiges ergibt eine null bei mir.

    Das liegt daran, dass Literale ebenfalls typisiert sind. Und

    1
    

    ist vom Typ int. Wenn int nun 32 Bit Datenbreite hat, ergibt

    1 << 32
    

    0, da das Ergebnis ebenfalls vom Typ int ist. Erst danach wird das Ergebnis test zugewiesen.

    Zwei Möglichkeiten, wie man dieses Problem beheben kann, wurden ja bereits genannt, ein Cast oder Suffix. Ich persönlich bin kein Freund von solchen Suffixen, da der Ausdruck ein zweites mal mit einer anderen Kennung typisiert. Das kann schnell zu Inkonsistenzen führen. Meine Empfehlung ist deshalb ein Cast. Benutze aber den functional-cast (wie bei gunnar) und keinen C-Cast.


  • Mod

    Gunnar_ schrieb:

    camper schrieb:

    dafür gibt es suffixe ...

    test = 1ULL << 34;
    

    Ja, aber sizeof(1ULL) ist doch wieder Systemabhaengig!?

    so wie sizeof( unsigned long long ) systemabhängig ist... sofern es existiert


Log in to reply