Forum: Compiler & IDEs Effiziente Umwandlung von langen Hex-Zahlen in Dezimal


von Bernhard L. (bernhard_r84)


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

von Yalu X. (yalu) (Moderator)


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 :)

von Bernhard L. (bernhard_r84)


Lesenswert?

Hallo Yalu,

funktioniert einwandfrei :) Vielen Dank!

lg

Bernhard

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.