BCD-Konvertierung

Obwohl die binärkodierte Dezimalzahl in der Regel nicht mehr für Protokolle und Datenspeicherungen verwendet wird, sind ihre Auswirkungen heute spürbar. Alle paar Jahre tauchen, in den Nachrichten, Fälle von gestörten Systemen auf, die plötzlich ein falsches Datum haben oder Geldbeträge falsch lesen/schreiben. Hier ist direkt zu sehen, wo BCD noch immer (vor allem durch die Kompatibilität zu älteren Systemen) verwendet wird. Zum Beispiel Datumszähler im CMOS-RAM, Geburtsdaten, in Transferprotokollen zwischen Bezahlgeräten oder zur Speicherung von Zugangsberechtigungsnummern.

Leider ist immer wieder zu sehen, dass die Konvertierung in native Zahlenformate über Umwege (oder mehrere Konvertierungen) gemacht wird. Das muss natürlich nicht sein.

Beispiel (Quellcode): bcd.cpp
Download (Quellcode): bcd.zip

Beschreibung

BCD-Aufbau Bei BCD wird jede Dezimalziffer des Wertes für sich gespeichert und zwar binär von Null bis Neun. Da hierfür nur maximal 4 Bit benötigt werden, wird oft die gepackte Variante von BCD eingesetzt. Das heißt, dass das obere und dann das untere Nibble eines Bytes benutzt werden um die Daten effektiver zu speichern. Dies ist auch die verbreiteste Variante.

Der Vorteil von BCD ist, es lässt sich ohne irgendeine "schwierige" Rechenoperation in eine Zeichenkette wandeln. Einfach das Nibble entnehmen und den ASCII-Code für das Zeichen der Null addieren und fertig ist eine Dezimalstelle.

Aufgrund der Tatsache, dass mehr Werte in ein Nibble passen, als Null bis Neun, werden die restlichen für Sonderaufgaben verwendet, dies ist aber abhängig von der Implementation. Gerne werden, mal Kommas oder Vorzeichen mitkodiert.

Durch den Beispielcode

Der Beispielcode, enthält eine Klasse (C++), die beinhaltet die Konvertierungsfunktion:

  • der Konstruktor

    CBCD(int nDigits);
    14
    

    Beim Erzeugen der Klasse wird die maximale Anzahl der Dezimalstellen angegeben.

  • von BCD

    unsigned int FromBCD(const uint8_t* pBCD);
    17
    

    Diese Funktion benötigt als Parameter einen Zeiger auf ein BCD kodiertes Datenfeld und gibt die umgewandelte Zahl zurück.

  • zu BCD

    void ToBCD(unsigned int nNonBCD, uint8_t* pBCD);
    28
    

    Diese Funktion benötigt als Parameter einen Zeiger auf ein Datenfeld und schreibt die BCD kodierte Zahl in dieses.

Codeanmerkungen

  1. Der Beispielcode erzeugt erzeugt gepacktes/verdichteten BCD-Code.

  2. Alle Programmargumente werden in BCD und zurück konvertiert:

    for(int n=1; n<argc; n++)
    51
    

    So ergibt

    ./bcd 1234 1010101 99999999
    

    die Ausgabe

    Binary coded decimal test...
    
      Original:       1234 ( 0x000004d2) ->     packed BCD:            (00 00 12 34)
    packed BCD:            (00 00 12 34) -> Converted back:       1234 ( 0x000004d2)
    
      Original:    1010101 ( 0x000f69b5) ->     packed BCD:            (01 01 01 01)
    packed BCD:            (01 01 01 01) -> Converted back:    1010101 ( 0x000f69b5)
    
      Original:   99999999 ( 0x05f5e0ff) ->     packed BCD:            (99 99 99 99)
    packed BCD:            (99 99 99 99) -> Converted back:   99999999 ( 0x05f5e0ff)