Effiziente Umwandlung von langen Hex-Zahlen in Dezimal

OP #3563148
Lesenswert?
• ▲
▼
Hallo!

Vor einiger Zeit hat Yalu X. (yalu) hier 
Beitrag "Umwandlung von langen Dezimalzahlen als String in Hex" einen super elegante Routine 
dec2bin gepostet die einen String von Dezimalzahlen in Binär/HEX 
umwandelt.

Meine Frage ist nun wie das Pendant dazu, also bin2dec aussieht um eine 
"beliebig" lange Binärzahl nach dezimal zu wandeln.

Beispiel: Aus A76F609E775AD3F28007A soll 12651036053835495342866554 
werden.
Wenn die Eingabe oder Ausgabe in einer anderen Reihenfolge ausgegeben 
wird, ist das kein Problem. Das kann man dann ja einfach passend 
umwandeln.

Grüße,

Bernhard
Moderator #3563384
Lesenswert?
• ▲
▼
Im Prinzip geht das genau andersherum:

In dec2bin wird in einer Schleife jeweils das Ergebnis mit 10
multipliziert und eine Dezimalziffer addiert.

In bin2dec wird in einer Schleife jeweils die Binärzahl durch 10
dividiert, der dabei entstehende Rest ergibt eine Dezimalziffer des
Ergbenisses.

Hier ist der entsprechende Code:
1
#include <stdio.h>
2
#include <stdint.h>
3

4
/* bin:     Binärzahl in Big-Endian, wird durch den Algorithmus überschrieben
5
 * binlen:  Anzahl der Bytes von bin
6
 * buffer:  Puffer für Dezimalstring, sollte mindestens 1 größer als die maximal
7
 *          zu erwartende Ziffernzahl sein
8
 * bufsize: Puffergröße
9
 * return:  Zeiger auf den Anfang des Dezimalstrings im Puffer, bei zu kleinem
10
 *          Puffer werden die höchstwertigen Ziffern abgeschnitten
11
 */
12
char *bin2dec(uint8_t *bin, uint8_t binlen, char *buffer, uint8_t bufsize) {
13
  uint16_t p;
14
  uint8_t  i, r;
15

16
  buffer[--bufsize] = '\0';
17
  while(binlen) {
18
    r = 0;
19
    for(i=0; i<binlen; i++) {
20
      p = (r << 8) | bin[i];
21
      bin[i] = p / 10;
22
      r = p - 10 * bin[i];
23
    }
24
    if(bufsize == 0)
25
      break;
26
    buffer[--bufsize] = '0' + r;
27
    if(*bin == 0) {
28
      bin++;
29
      binlen--;
30
    }
31
  }
32
  return buffer + bufsize;
33
}
34

35
int main(void) {
36
  uint8_t bin[] = { 0x0A, 0x76, 0xF6, 0x09, 0xE7, 0x75, 0xAD, 0x3F, 0x28, 0x00, 0x7A };
37
  char buffer[30], *dec;
38

39
  dec = bin2dec(bin, sizeof bin, buffer, sizeof buffer);
40
  printf("%s\n", dec);
41

42
  return 0;
43
}

Die Division der großen Binärzahl durch 10 geschieht in der inneren
Schleife. Das Divisionsergebnis steht anschließend wieder in bin, der
Divisionsrest in r. Da bin mit jeder Division kleiner wird, entstehen
führende Nullbytes, die mit if(*bin == 0) {...} abgeschnitten werden.
Sobald die Länge der Binärzahl auf 0 geschrumpft ist, ist die
Konvertierung abgeschlossen. Bei drohendem Pufferüberlauf von buffer
wird der Algorithmus vorzeitig abgebrochen.

Ich hoffe, dass nicht allzu viele Fehler in dem Code sind :)

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.