Fabian St.: BCD-Kodierung?

Hi!

Ich habe hier eine in C geschriebene dll, die mir gewisse Funktionen zur Vefügung stellt. Unter anderem auch GetDllVersion(), die laut Dokumentationen „eine Integervariable zurückgibt, bei der jedes Byte eine Stelle der Versionsnummer ist (ähnlich BCD-Kodierung).“
Nun bin ich dabei, mit Hilfe des ctypes-Python-Modul einen Python-Wrapper für diese Dll zur erstellen. Wenn ich die betreffene Funktion aufrufe bekomme ich einen Wert wie „17629184“. Wie bekomme ich nun daraus jedoch meine Versionsnummer? Mein Problem fängt nämlich bereits damit an, dass ich auch nach eine Google-Recherche mit dem Begriff „BCD-Kodierung“ nicht wirklich weiterkomme.

Grüße,
Fabian St.

  1. Hello,

    Binary Coded Decimals arbeit mit Halbbytes.
    Es werden also immer vier Bit für die Signierung eines dezimalen Digits verwendet.
    Die Werte A bis F werden also verschwendet.

    Um das rückübersetzen zu können, musst Du zusätzlich wissen, ob BigEndian oder LittleEndian-Notation verwendet wird.

    Harzliche Grüße vom Berg
    http://www.annerschbarrich.de

    Tom

    --
    Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
    Nur selber lernen macht schlau

    1. Hi!

      Hello,

      Binary Coded Decimals arbeit mit Halbbytes.
      Es werden also immer vier Bit für die Signierung eines dezimalen Digits verwendet.
      Die Werte A bis F werden also verschwendet.

      Um das rückübersetzen zu können, musst Du zusätzlich wissen, ob BigEndian oder LittleEndian-Notation verwendet wird.

      Puhh, das ist eine gute Frage. Als Beispiel wird folgendes angefügt: 0x010A0203 entspricht 1.10.2.3
      Hilft das eventuell weiter?

      Grüße,
      Fabian St.

      1. Hallo,

        Als Beispiel wird folgendes angefügt: 0x010A0203 entspricht 1.10.2.3
        Hilft das eventuell weiter?

        ja klar, das kann man doch beinahe im Klartext lesen:
         0x01->1, 0x0A->10, 0x02->2, 0x03->3

        Dann hatte ich also Recht mit meiner Annahme.

        Schönes Wochenende noch,
         Martin

        --
        Der Mensch denkt, Gott lenkt.
        Der Mensch dachte, Gott lachte.
  2. Hallo Fabian,

    Ich habe hier eine in C geschriebene dll, [...] die laut Dokumentationen „eine Integervariable zurückgibt, bei der jedes Byte eine Stelle der Versionsnummer ist (ähnlich BCD-Kodierung).“

    aha. Soweit klar.

    Nun bin ich dabei, mit Hilfe des ctypes-Python-Modul einen Python-Wrapper für diese Dll zur erstellen. Wenn ich die betreffene Funktion aufrufe bekomme ich einen Wert wie „17629184“. Wie bekomme ich nun daraus jedoch meine Versionsnummer?

    Indem du diesen Integerwert in einzelne Bytes aufsplittest.
    17629184 ist 0x010D0000, dann bekommst du also die Bytes 1,13,0,0. Ergibt das eine plausible Versionsnummer, vielleicht 1.13?

    Mein Problem fängt nämlich bereits damit an, dass ich auch nach eine Google-Recherche mit dem Begriff „BCD-Kodierung“ nicht wirklich weiterkomme.

    Das ist hier auch irreführend, weil der Wert nicht wirklich BCD-codiert ist. Bei der BCD-Codierung wird jede Dezimalziffer exakt auf vier Bits abgebildet, die dann die Werte 0000..1001 annehmen können. Die weiteren, theoretisch möglichen Bitmuster 1010..1111 werden nicht verwendet. Der Vorteil der Methode ist, dass sich BCD-codierte Zahlen dann sehr leicht in Ausgabestrings umwandeln lassen: Einfach ein Nibble nach dem anderen nehmen, 0x30 addieren und als ASCII-Zeichen ausgeben.
    Mit BCD-codierten Zahlen wirklich zu rechnen ist dagegen sehr aufwendig.

    So long,
     Martin

    --
    Es gibt Tage, da gelingt einem einfach alles.
    Aber das ist kein Grund zur Sorge; das geht vorbei.
    1. Hello out there!

      Mit BCD-codierten Zahlen wirklich zu rechnen ist dagegen sehr aufwendig.

      Der Z80 hatte die Addition/Subtraktion von BCD schon verdrahtet.

      So groß kann der Aufwand nicht sein.

      See ya up the road,
      Gunnar

      --
      “Remember, in the end, nobody wins unless everybody wins.” (Bruce Springsteen)
      1. Moin!

        Mit BCD-codierten Zahlen wirklich zu rechnen ist dagegen sehr aufwendig.

        Der Z80 hatte die Addition/Subtraktion von BCD schon verdrahtet.

        So groß kann der Aufwand nicht sein.

        Der 6510 im C64 kennt ebenfalls einen BCD-Rechenmodus.

        Der Vorteil ist, dass Rundungsfehler genau dort auftreten, wo der Mensch sie erwartet. Negativ ist der erhöhte Speicherverbrauch.

        - Sven Rautenberg

        --
        My sssignature, my preciousssss!
        1. Hallo,

          Der 6510 im C64 kennt ebenfalls einen BCD-Rechenmodus.

          ja, stimmt. Im Gegensatz zur x86-Familie kann der liebenswerte 8-bitter aber in BCD nur addieren und subtrahieren. Okay, eigentlich kann er grundsätzlich nur addieren und subtrahieren; Multiplikation und Division sind für diese CPU Fremdwörter. ;-)

          Der Vorteil ist, dass Rundungsfehler genau dort auftreten, wo der Mensch sie erwartet.

          Stimmt, so hab ich das noch gar nicht gesehen. Ich habe als Vorteil bisher nur die einfache Umwandlung in Strings gesehen.

          Schönen Abend noch,
           Martin

          --
          Ja, ja... E.T. wusste schon, warum er wieder nach Hause wollte.
      2. Hallo Gunnar,

        Mit BCD-codierten Zahlen wirklich zu rechnen ist dagegen sehr aufwendig.
        Der Z80 hatte die Addition/Subtraktion von BCD schon verdrahtet.
        So groß kann der Aufwand nicht sein.

        das stimmt, einige CPUs haben Ansätze von BCD-Arithmetik schon eingebaut. Selbst die x86-Prozessorfamilie hat Instruktionen, mit denen zumindest die vier Grundrechenarten in BCD recht einfach zu programmieren sind.

        Mein Urteil bezog sich eher auf das Selbst-Implementieren, wenn die CPU das nicht von sich aus kann.

        Schönen Abend noch,
         Martin

        --
        Der Bäcker schlägt die Fliegen tot
        Und macht daraus Rosinenbrot.
    2. Hi Martin!

      Nun bin ich dabei, mit Hilfe des ctypes-Python-Modul einen Python-Wrapper für diese Dll zur erstellen. Wenn ich die betreffene Funktion aufrufe bekomme ich einen Wert wie „17629184“. Wie bekomme ich nun daraus jedoch meine Versionsnummer?

      Indem du diesen Integerwert in einzelne Bytes aufsplittest.
      17629184 ist 0x010D0000, dann bekommst du also die Bytes 1,13,0,0. Ergibt das eine plausible Versionsnummer, vielleicht 1.13?

      Vielen Dank für deine Erklärung! Das hilft mir schon mal sehr weiter. Jetzt habe ich jedoch noch eine Frage: Warum ist 0x01, 0x0D, etc. genau ein Byte, d.h. 8bit. Irgendwie hängt es bei mir bereits daran ...

      Mein Problem fängt nämlich bereits damit an, dass ich auch nach eine Google-Recherche mit dem Begriff „BCD-Kodierung“ nicht wirklich weiterkomme.

      Das ist hier auch irreführend, weil der Wert nicht wirklich BCD-codiert ist. Bei der BCD-Codierung wird jede Dezimalziffer exakt auf vier Bits abgebildet, die dann die Werte 0000..1001 annehmen können. Die weiteren, theoretisch möglichen Bitmuster 1010..1111 werden nicht verwendet. Der Vorteil der Methode ist, dass sich BCD-codierte Zahlen dann sehr leicht in Ausgabestrings umwandeln lassen: Einfach ein Nibble nach dem anderen nehmen, 0x30 addieren und als ASCII-Zeichen ausgeben.
      Mit BCD-codierten Zahlen wirklich zu rechnen ist dagegen sehr aufwendig.

      Ah, ok. Kein Wunder, dass mich das also nicht wirklich weiter gebracht hat.

      Grüße,
      Fabian St.

      1. Hallo,

        17629184 ist 0x010D0000, dann bekommst du also die Bytes 1,13,0,0. Ergibt das eine plausible Versionsnummer, vielleicht 1.13?

        Vielen Dank für deine Erklärung! Das hilft mir schon mal sehr weiter. Jetzt habe ich jedoch noch eine Frage: Warum ist 0x01, 0x0D, etc. genau ein Byte, d.h. 8bit. Irgendwie hängt es bei mir bereits daran ...

        Oha. Back to the basics. Wie sag ich's meinem Kinde ...
        Also, 1 Byte hat 8 Bit. Eine hex-Ziffer kann 16 Werte annehmen, entspricht damit genau 4 Bit (weil 2^4=16). Ergo stellen zwei hex-Ziffern eine Informationsmenge von 8 Bit dar. Diese schöne, leicht überschaubare Beziehung ist der Grund, warum vor allem maschinennah arbeitende Programmierer das Hexadezimalsystem lieben.

        Naja, abgesehen davon klingt es doch viel besser, wenn man einer Frau, die 40 wird, zum 28. Geburtstag gratuliert. ;-)

        So long,
         Martin

        --
        Programmierer (m), seltener auch ~in (w):
        Irdische, i.a. humanoide Lebensform, die in einem komplizierten biochemischen Prozess Kaffee, Cola und Pizza in maschinenlesbaren Programmcode umwandelt.
        P~ bilden gelegentlich mit ihresgleichen kleine Gruppen, sogenannte Communities, sind aber ansonsten meist scheue Einzelgänger.
        P~ sind vorwiegend nachtaktiv und ohne technische Hilfsmittel nur eingeschränkt lebensfähig.
        1. Hello,

          Naja, abgesehen davon klingt es doch viel besser, wenn man einer Frau, die 40 wird, zum 28. Geburtstag gratuliert. ;-)

          Du wirst mir immer sympathischer :-))

          Harzliche Grüße vom Berg
          http://www.annerschbarrich.de

          Tom

          --
          Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
          Nur selber lernen macht schlau

          1. Hallo Tom,

            Naja, abgesehen davon klingt es doch viel besser, wenn man einer Frau, die 40 wird, zum 28. Geburtstag gratuliert. ;-)

            Du wirst mir immer sympathischer :-))

            danke für die Blumen, ich könnte mir Schlimmeres vorstellen ... *g*

            Bye,
             Martin

            --
            Ja, ja... E.T. wusste schon, warum er wieder nach Hause wollte.
            1. Hello,

              danke für die Blumen, ich könnte mir Schlimmeres vorstellen ... *g*

              Wie jetzt? Z. Bsp., wenn ich Dich zum Probeessen von 10 http://harte-harzer.de zwingen würde? Die sind wirklich teuflisch und nix für Weicheier. *gg*

              Harzliche Grüße vom Berg
              http://www.annerschbarrich.de

              Tom

              --
              Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
              Nur selber lernen macht schlau

              1. Hi!

                Wie jetzt? Z. Bsp., wenn ich Dich zum Probeessen von 10 http://harte-harzer.de zwingen würde? Die sind wirklich teuflisch und nix für Weicheier. *gg*

                Ich hab übrigens immer noch keine gekriegt - dafür hat meine Stamm-Kneipe mittlerweile nen neuen Wirt :-\

                Gruß aus Iserlohn

                Martin

                --
                Wer anderen eine Bratwurst brät, hat ein Bratwurstbratgerät.
                Selfcode: ie:{ fl:( br:^ va:) ls:# fo:| rl:( n4:( ss:| de:> js:) ch:? sh:( mo:| zu:)
              2. Hallo Tom,

                Z. Bsp., wenn ich Dich zum Probeessen von 10 http://harte-harzer.de zwingen würde? Die sind wirklich teuflisch und nix für Weicheier. *gg*

                sind das nun diese salamiähnlichen Würstchen? Die würde ich tatsächlich gern mal probieren, da bin ich recht experimentierfreudig. Und ein Alibi für zwei Bier mehr ist auch nicht schlecht. Ich hatte nur bisher gedacht, es handle sich im eine Käsesorte - den Begriff "Harzer" hatte ich fest mit Käse assoziiert.

                Btw, wieso wird man eigentlich (wenn man neugierig ist, was da wohl drin sein mag), von http://www.harte-harzer.de/ingredenzien/ immer sofort wieder auf die Startseite umgeleitet?

                Schönen Abend noch,
                 Martin

                --
                Zwischen Leber und Milz
                passt immer noch'n Pils.
                1. Hello,

                  Btw, wieso wird man eigentlich (wenn man neugierig ist, was da wohl drin sein mag), von http://www.harte-harzer.de/ingredenzien/ immer sofort wieder auf die Startseite umgeleitet?

                  Vielleicht liegt es an der Browse? *gg*

                  Harzliche Grüße vom Berg
                  http://www.annerschbarrich.de

                  Tom

                  --
                  Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
                  Nur selber lernen macht schlau

                  1. Hi,

                    Btw, wieso wird man eigentlich (wenn man neugierig ist, was da wohl drin sein mag), von http://www.harte-harzer.de/ingredenzien/ immer sofort wieder auf die Startseite umgeleitet?

                    Vielleicht liegt es an der Browse? *gg*

                    nein, es liegt eher daran, dass man bei einem Request nach /ingredenzien/ (man beachte die falsche Schreibweise, richtig wäre: ingredienzen) sofort mit einem Status 302 nach http://www.harte-harzer.de/ umgeleitet wird (alle anderen Unterseiten kommen korrekt). Egal ob IE, Firefox, Opera. Der Firefox (1.0.4) zeigt dann außerdem auf http://www.harte-harzer.de/ nur eine leere Seite und behauptet, der Quelltext der Seite sei nicht mehr als das hier:

                    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><title></title></head><body></body></html>

                    Diesen Bug habe ich schon bei einigen Seiten festgestellt, weiß aber bis heute nicht, worauf er zurückzuführen ist.

                    Ciao,
                     Martin

                    --
                    Man soll den Tag nicht vor dem Abend loben.
                    Und den Mann nicht vor dem Morgen.
                      (alte Volksweisheit)
        2. Hi!

          Vielen Dank für deine Erklärung! Das hilft mir schon mal sehr weiter. Jetzt habe ich jedoch noch eine Frage: Warum ist 0x01, 0x0D, etc. genau ein Byte, d.h. 8bit. Irgendwie hängt es bei mir bereits daran ...

          Oha. Back to the basics. Wie sag ich's meinem Kinde ...
          Also, 1 Byte hat 8 Bit. Eine hex-Ziffer kann 16 Werte annehmen, entspricht damit genau 4 Bit (weil 2^4=16). Ergo stellen zwei hex-Ziffern eine Informationsmenge von 8 Bit dar. Diese schöne, leicht überschaubare Beziehung ist der Grund, warum vor allem maschinennah arbeitende Programmierer das Hexadezimalsystem lieben.

          Ah, ok. Ich habs verstanden und kann nun wieder weitermachen :-)

          Grüße,
          Fabian St.

        3. Hello out there!

          Naja, abgesehen davon klingt es doch viel besser, wenn man einer Frau, die 40 wird, zum 28. Geburtstag gratuliert. ;-)

          Naja, bei denen magst du dich damit einschleimen. Aber gratulier mal einer, die 30 wird, zum 1E. Geburtstag; die wird dich nur blöd ankucken – verkackt! ;-)

          See ya up the road,
          Gunnar

          --
          “Remember, in the end, nobody wins unless everybody wins.” (Bruce Springsteen)
          1. Hello,

            Naja, bei denen magst du dich damit einschleimen. Aber gratulier mal einer, die 30 wird, zum 1E. Geburtstag; die wird dich nur blöd ankucken – verkackt! ;-)

            Insbesondere, wenn sie es als Exponent annimmt und glaubt, dass da wohl der Faktor 10 drinstecken müsste...

            Harzliche Grüße vom Berg
            http://www.annerschbarrich.de

            Tom

            --
            Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
            Nur selber lernen macht schlau

          2. Hi,

            Naja, abgesehen davon klingt es doch viel besser, wenn man einer Frau, die 40 wird, zum 28. Geburtstag gratuliert. ;-)

            Naja, bei denen magst du dich damit einschleimen.

            Hmm, "einschleimen" hätte ich das jetzt nicht genannt. Vielleicht eine kleine Flirt-Notlüge. ;-)
            Ich hab das letztes Jahr tatsächlich bei einer Kollegin gebracht - aber die würde mit ihren 40 Jahren auch *wirklich* noch locker für 30 durchgehen!

            Aber gratulier mal einer, die 30 wird, zum 1E. Geburtstag; die wird dich nur blöd ankucken – verkackt! ;-)

            Ja, das ist ein doofes Alter. Von 1A..1F geht man dann am besten taktvoll über die Erwähnung irgendwelcher Zahlen hinweg. :-)

            Ciao,
             Martin

            --
            Du kannst dem Leben nicht mehr Tage geben.
            Aber dem Tag mehr Leben.
  3. Hallo Fabian,

    „eine Integervariable zurückgibt, bei der jedes Byte eine Stelle der Versionsnummer ist.“

    Das sagt doch eigentlich schon alles. Du musst also nur die einzelnen Bytes auswählen:

    byte wert = (version & (255 << i * 8)) >> i * 8;

    i ist das auszulesende byte (erstes byte: i = 0)

    Also erst ein 1-Byte (255) an die Stelle des auszulesenden Bytes shiften, dann und-Verknüpfen mit der Version und dann das ergebnis wieder zurück-shiften (um die überflüssigen 0-Bits loszuwerden).

    Grüße

    Daniel

    1. Hi Daniel,

      byte wert = (version & (255 << i * 8)) >> i * 8;
      i ist das auszulesende byte (erstes byte: i = 0)

      Also erst ein 1-Byte (255) an die Stelle des auszulesenden Bytes shiften, dann und-Verknüpfen mit der Version und dann das ergebnis wieder zurück-shiften (um die überflüssigen 0-Bits loszuwerden).

      Warum so kompliziert? Andersrum ist es einfacher, dann brauchst du nur noch einmal zu schieben:

      b = (version>>(8*i)) & 0xFF

      Erst alles nach rechts schieben, dann die gewünschten Bits mit einer konstanten Maske isolieren.

      Ciao,
       Martin

      --
      Lache, und die Welt wird mit dir lachen.
      Schnarche, und du schläfst allein.
      1. Hallo Martin,

        b = (version>>(8*i)) & 0xFF

        Überzeugt irgendwie ;-)

        Grüße

        Daniel