ein integer in zwei short teilen



  • Hallo Zusammen!

    Ich habe eine Funktion...

    int getDLLVersion(void);
    

    ..die mir eine Vesionsnummer zurück gibt. Laut Dokumentation stehen in den "höherwertigen 16 Bit die Hauptversion" und und in den anderen 16 Bit die Unterversion.
    Bsp.: 0x00010003 bedeutet Version 1.03

    Jetzt wollte ich die Version direkt in ein Struct speichern:

    struct DLLVersion {
      short minor;
      short maior;
    }
    DLLVersion version;
    version = getDLLVersion();
    

    Leider geht das so nicht (was ich schon vor dem Kompilieren ahnte).
    Ich weiß jetzt nur leider nicht weiter. Ein Tipp wäre hilfreich. Wenn der Aufwand dafür zu groß ist, speichere ich die Version halt nur als int.

    Danke für die Hilfe.
    Gerrit



  • class dll_version_t {
    
    	private:
    
    		unsigned short m_major;
    		unsigned short m_minor;
    
    	public:
    
    		dll_version_t( ) : m_major( 0 ), m_minor( 0 ) { }
    		dll_version_t( int dll_version ) : m_major( ( dll_version >> 16 ) & 0x00ff ), m_minor( dll_version & 0x00ff ) { }
    		dll_version_t( unsigned short dll_version_major, unsigned short dll_version_minor ) : m_major( dll_version_major ), m_minor( dll_version_minor ) { }
    
    		unsigned short get_major( ) { return m_major; }
    		unsigned short get_minor( ) { return m_minor; }
    };
    
    /* ... */
    
    dll_version_t version( getDLLVersion( ) );
    

    greetz, Swordfish



  • Danke für die schnelle Antwort.
    Für mich ist besonders die Zeile interessant:

    dll_version_t( int dll_version ) : m_major( ( dll_version >> 16 ) & 0x00ff ), m_minor( dll_version & 0x00ff ) { }
    

    Binäre operationen sind also die Lösung meines Problems. Ich habe mich also mal im Netz schlau gemacht und frage mich nun, ob nicht hier:

    ...m_major( ( dll_version >> 16 ) & 0x00ff )...
    

    die UND-Operation überflüssig (redundant) ist, da ">>" doch automatisch mit 0 auffüllt. Mache ich einen Denkfehler oder ist das zur Sicherheit, weil die Compiler das unterschiedlich machen?

    Noch viel wichtiger:
    Die gespeicherten werte sind ja dezimal. Die Versionsnummern sind aber Hexadezimal ausgedrückt.
    Was ich meine: Die Versionsnummer lautet z.B.: 3.92
    Mein major-Hex-Wert ist also 3
    mein minor-Hex-Wert ist 92
    In meinem Struct stehen aber ja Integerwerte also 3 und 146. Wie mache ich also eine Hex-92 zu einer Dec-92?
    Beim googlen bekomme ich immer nur Dec-Hex-Konverter, was mir ja nun nix bringt.

    Danke nochmal.
    Gerrit



  • müsste es nicht 0xFFFF sein?



  • Nein. Ich glaub nicht.
    int & 0xFFFF ist doch wieder das gleiche int.

    Aber nach wie vor finde ich nicht heraus, wie ich aus der hex-92 eine int-92 machen kann. Es muss doch einfacher gehen als so (funktionieren tuts):

    int ver = getDLLVersion();
    
    		// dieser Umweg muss noch ersetzt werden
    		int tmp;
    		float bruch;
    
    		MEDllVersion.major = ver >> 16;
    		bruch = float(MEDllVersion.major)/16;
    		tmp = int(floor(bruch));
    		MEDllVersion.major = tmp*10 + (MEDllVersion.major - tmp*16);
    
    		MEDllVersion.minor = ver & 0x00FF;
    		bruch = float(MEDllVersion.minor)/16;
    		tmp = int(floor(bruch));
    		MEDllVersion.minor = tmp*10 + (MEDllVersion.minor - tmp*16);
    


  • das "& 0x00ff" macht schon Sinn, schliesslich garantiert dir ja niemand, dass "int" genau 32 Bit gross ist. Auf einem 64-Bit-Betriebssystem ist ein int 64 Bit gross, und dann funktioniert dein Code ohne dem "&" nicht mehr.

    gerritgoetzen schrieb:

    Noch viel wichtiger:
    Die gespeicherten werte sind ja dezimal. Die Versionsnummern sind aber Hexadezimal ausgedrückt.
    Was ich meine: Die Versionsnummer lautet z.B.: 3.92
    Mein major-Hex-Wert ist also 3
    mein minor-Hex-Wert ist 92
    In meinem Struct stehen aber ja Integerwerte also 3 und 146. Wie mache ich also eine Hex-92 zu einer Dec-92?

    Bist du dir sicher dass dich das ueberhaupt interessiert?
    Falls ja, ein hex-to-dec ist relativ trivial:

    int hex2dec(int hex)
    {
      int dec = 0;
      while(hex > 16)
      {
        dec = (dec * 16) + (hex % 16);
        hex /= 16;
      }
      return dec + hex;
    }
    

    (ohne Gewaehr)



  • hmmmmmmmm schrieb:

    müsste es nicht 0xFFFF sein?

    Richtig!



  • Man muss da nichts umwandeln, alle Zahlen werden doch binär dargestellt. Ob dezimal oder hexadezimal ist doch nur eine Interpretationssache:

    // zuerst dezimal:
    std::cout << version.get_major() << '.' << version.get_minor() << std::endl;
    // dann hexadezimal:
    std::cout << std::hex << version.get_major() << '.' << std::hex versíon.get_minor() << std::endl;
    

    Ich würde aber den <<-Operator für die Klasse von Swordfisch überladen, wenn du die Version öfter mal ausgeben willst (zB in eine Datei). Machst du das nicht, sondern benutzt sie nur zum Vergleich mit anderen Versionen, ist das ganz ja vollkommen irrelevant, da 0x92 == 146 == 0222 == 10010010 (binär).

    Gruß
    Don06



  • Mit dem &0x00FF leuchtet mir jetzt ein. Danke.

    Nun zum anderen Problem. Ich hab ja die Versionsnummern in meinem Struct drin. "major" und "minor" sind als "short" (also 16bit) dort drin.

    typedef struct _DLL_VERSION
    {
    	unsigned short major;
    	unsigned short minor;
    } DLL_VERSION, *PDLL_VERSION;
    

    Wenn ich nun so

    DLL_VERSION version;
    int ver = getDLLVersion();
    version.major = (ver >> 16) & 0x00FF;
    version.minor = ver & 0x00FF;
    

    mein struct fülle, stehen dort folgende werte:
    major = 3 // Hex: 3
    minor = 146 // Hex: 92

    Die Versionsnummer lautet aber nicht 3.146 sondern 3.92. Es geht nämlich um die Hex-Werte und nicht um die dezimalen (so ist es in der Dokumentation der Funktion erklärt). Ich möchte also folgendes speichern:
    major = 3
    minor = 92

    Deshalb auch meine Umrechnung. Ich denke aber das das einfacher gehen muss. Funktionieren tuts ja. Ich hoffe ich habe mich nun verständlicher ausgedrückt.

    Danke
    Gerrit

    (jetzt wart Ihr schneller mit tippen :))



  • prinzipiell ist das ja machbar,
    aber hast du dir mal überlegt, was passiert, wenn da mal statt 92 ein 9F steht oder so?
    wie willst du das dann einfach mal als Dezimalzahl werten?



  • Was du von getDLLVersion( ) bekommst, sind einen Haufen bits. Nicht mehr und nicht weniger. Nachdem du den int in zwei unsigned short s aufgeteilt hast, hast du wieder einen Haufen bits. Wie Du die interpretierst, ist eine andere Geschichte.

    Ist die DLL von Dir, oder bist du "nur" Benutzer? Wenn der Entwickler der DLL vorgibt, dass die Versionsnummern Hexadezimal zu verstehen sind, dann gib sie Hexadezimal aus und alles ist gut.

    greetz, Swordfish



  • Eine Möglichkeit wäre auch noch ein Bitset:

    struct dll_version_t
    {
        unsigned major : 16;
        unsigned minor : 16;
    };
    
    dll_version_t version = *reinterpret_cast<dll_version_t*> (getDLLVersion ());
    


  • Verdammt, ich bin immer noch viel zu C-lastig. *kopfgegentischplatteknallt* 😡

    greetz, Swordfish



  • wenn es sowieso/nur für windows ist, gibts zu diesem zweck die wunderschönen makros LOWORD und HIWORD.



  • winner schrieb:

    [...] wunderschönen makros LOWORD und HIWORD.

    contradictio in adiecto 😉

    greetz, Swordfish



  • Swordfish schrieb:

    contradictio in adiecto 😉

    genau, ich wollte ja noch "oxymoron" als user hinschreiben 😞



  • am einfachsten wäre es mit einem short pointer.

    short getUpper( long value )
    {
        short * ptr = (short*) &value;
        ++ptr;
        return *ptr;
    }
    
    short getLower( long value )
    {
        short * ptr = (short*) &value;
        return *ptr;
    }
    


  • plongor schrieb:

    am einfachsten wäre es mit einem short pointer.

    Wohl eher am unsichersten. Was, wenn ein short 4 Bytes breit ist?

    greetz, Swordfish



  • Gegenfrage, was ist wenn der Integer 33 Byte groß ist und gar nicht durch 2 teilbar ist?



  • Sch***egal, denn:

    gerritgoetzen schrieb:

    Laut Dokumentation stehen in den "höherwertigen 16 Bit die Hauptversion" und und in den anderen 16 Bit die Unterversion.

    greetz, Swordfish


Anmelden zum Antworten