Forum: Mikrocontroller und Digitale Elektronik Hex Seriennummer in Dec


von Andreas M. (andreas_mue)


Lesenswert?

Hallo,
ich bin hier ganz neu und auch im C programmieren neu.
Ich brauche eine Funktion um aus einer Hex Seriennummer eine Dec 
Seriennummer zu machen.

z.B.:
char Hex [8] = {0xAB, 0xCD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
char Dec [16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x05, 0x26, 0x51};

Zur Erklärung: char Hex wird von hinten nach vorne gelesen. Also heißt 
die Zahl 0000...CDAB und diese möchte ich umrechnen in 0000...52651. Nur 
das es ausgegeben werden soll wie es bei char Dec steht.

Mein Problem ist, das ich nicht die komplette Zahl umrechnen kann. Ich 
kann zwar CD und AB ausrechnen aber nicht CDAB zu 52651. Wie schaff ich 
das? Jemand eine Idee?

Gruß
Andreas

: Verschoben durch User
von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Andreas Müller schrieb:
> Jemand eine Idee?
Multipliziere CD mit 256. Das ist nämlich die Wertigkeit dieses 
Bytes...

Und wenn es ein EF gäbe, dann müsstest du das mit 256*256 
multiplizieren.

Dann hast du den Wert als "normalen" Integer. Den musst du dann mit 
itoa() oder sprintf() in eine Zeichenkette umwandeln.

: Bearbeitet durch Moderator
von Michael H. (dowjones)


Lesenswert?

Falls ich das richtig verstanden habe, dann soll eine 16-stellige 
Hexadezimalzahl nach BCD umgewandelt werden. Das könnte man mit dem 
+3-Algorithmus machen:
1
#include <stdio.h>
2
3
// add-3-algo
4
void hex2bcd(char hex[], char dec[]) {
5
6
  int p, i, v, c;
7
8
  for(i=0; i<16; i++) {
9
    dec[i] = 0;
10
  }
11
12
  for(p=63; p>=0; p--) {
13
    c = (hex[ p>>3 ] >> (p&0x07)) & 0x01;
14
    for(i=15; i>=0; i--) {
15
      v = (unsigned char)dec[i];
16
      v += (v&0x0f) >= 0x05 ? 0x03 : 0x00;
17
      v += (v&0xf0) >= 0x50 ? 0x30 : 0x00;
18
      v = (v<<1) + c;
19
      c = v>>8;
20
      dec[i] = v&0xff;
21
    }
22
  }
23
}
24
25
26
27
// test
28
void main(int argc, char** argv) {
29
30
  char Hex [8] = {0xAB, 0xCD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
31
  char Dec [16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
32
            0x00, 0x00, 0x00, 0x00, 0x05, 0x26, 0x51};
33
  int i;
34
  
35
  hex2bcd(Hex, Dec);
36
37
  for(i=0; i<16; i++) {
38
    printf(".%02x", (unsigned char)Dec[i]);
39
  }
40
  printf("\n");
41
}

Schnell ist es nicht unbedingt, sollte aber funktionieren.

von Stefan F. (Gast)


Lesenswert?


von vloki (Gast)


Lesenswert?

Andreas Müller schrieb:
> Zur Erklärung: char Hex wird von hinten nach vorne gelesen. Also heißt
> die Zahl 0000...CDAB und diese möchte ich umrechnen in 0000...52651. Nur
> das es ausgegeben werden soll wie es bei char Dec steht.

Es gibt eigentlich weder hex noch dezimal Zahlen sondern nur Bitmuster 
die als Binärzahlen interpretiert werden können.
Das Bitmuster wird dann in eine Zeichenkette umgerechnet die auf der 
Anzeige wie eine Dezimalzahl aussieht.
Wenn die Bytereihenfolge stimmt (Litttle Endian / Big Endian), dann 
brauchst du nur die Adresse des Lowbyte als eine Adresse auf ein 64bit 
Integer zu betrachten und kannst dir jegliche Umrechnung sparen.
Bei der Anzeige gibst du dann nur noch an, wie du es sehen willst 
(dezimal)

von Besucher (Gast)


Lesenswert?

vloki schrieb:
> Es gibt eigentlich weder hex noch dezimal Zahlen sondern nur Bitmuster
> die als Binärzahlen interpretiert werden können.
> Das Bitmuster wird dann in eine Zeichenkette umgerechnet die auf der
> Anzeige wie eine Dezimalzahl aussieht.

Die Sache ist, das man ein Bitmuster eben nicht immer als Binärzahl 
interpretieren möchte. Für andere Interpretationen - wie z.B. BCD - muss 
man das Bitmuster entsprechend umrechnen. Und die Frage ist eben wie 
diese Umrechnung ausschaut.
Da ist die Funktion welche Michael H. gepostet hat durchaus nützlich, 
die scheint mit beliebig langen Bitmustern ungehen zu können. Auch wenn 
der C-Compiler bzw. die Bibliothek das in diesem Fall (64bit Zahl) 
automatisch handhaben können, so finde ich selber es dennoch interessant 
mal zu sehen wie das algorithmisch gedeichselt wird.
Thumps up!

von Dennis H. (c-logic) Benutzerseite


Lesenswert?

Andreas Müller schrieb:
> Hallo,
> ich bin hier ganz neu und auch im C programmieren neu.
> Ich brauche eine Funktion um aus einer Hex Seriennummer eine Dec
> Seriennummer zu machen.
>
> z.B.:
> char Hex [8] = {0xAB, 0xCD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
> char Dec [16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> 0x00, 0x00, 0x00, 0x00, 0x05, 0x26, 0x51};


Datentyp uint64_t.
Wenns ein little endian System ist geht auch gleich
*((uint64_t*)Hex)

Den Wert mußt man sich dann nehmen und BCD-Konvertieren.
Das kann sich aber enorm auf die Rechenzeit auswirken.

: Bearbeitet durch User
von Volker S. (vloki)


Lesenswert?

Besucher schrieb:
> Die Sache ist, das man ein Bitmuster eben nicht immer als Binärzahl
> interpretieren möchte. Für andere Interpretationen - wie z.B. BCD - muss
> man das Bitmuster entsprechend umrechnen. Und die Frage ist eben wie
> diese Umrechnung ausschaut.

Ja, bei BCD muss ich dir recht geben.
Alles andere (ob hex, oct, dec, bin) wird binär, unabhängig davon wie 
wir es dem Compiler mitteilen.
Das Problem habe ich häufig, wenn ich Studenten klar machen muss, dass 
alles nur in Ihren Köpfen existiert und das was sie auf der Anzeige 
sehen noch nicht mal eine Zahl sondern eine Zeichenkette ist.

von Peter (Gast)


Lesenswert?

Michael H. schrieb:

>   for(p=63; p>=0; p--) {
>     c = (hex[ p>>3 ] >> (p&0x07)) & 0x01;
>     for(i=15; i>=0; i--) {
>       v = (unsigned char)dec[i];
>       v += (v&0x0f) >= 0x05 ? 0x03 : 0x00;
>       v += (v&0xf0) >= 0x50 ? 0x30 : 0x00;
>       v = (v<<1) + c;
>       c = v>>8;
>       dec[i] = v&0xff;
>     }
>   }
> }

Kann mir jemand diese Schleife erklären? Was genau passiert hier?
Schritt für Schritt am besten.

von uwe (Gast)


Lesenswert?

Willst du es so umrechenen:
FFFFFFFF = 255.255.255.255
oder
FFFFFFFF = 4294967295
oder
FFFFFFFF = -1

von Karl H. (kbuchegg)


Lesenswert?

Peter schrieb:
> Michael H. schrieb:
>
>>   for(p=63; p>=0; p--) {
>>     c = (hex[ p>>3 ] >> (p&0x07)) & 0x01;
>>     for(i=15; i>=0; i--) {
>>       v = (unsigned char)dec[i];
>>       v += (v&0x0f) >= 0x05 ? 0x03 : 0x00;
>>       v += (v&0xf0) >= 0x50 ? 0x30 : 0x00;
>>       v = (v<<1) + c;
>>       c = v>>8;
>>       dec[i] = v&0xff;
>>     }
>>   }
>> }
>
> Kann mir jemand diese Schleife erklären? Was genau passiert hier?
> Schritt für Schritt am besten.

Kabel deinen PC hoch.
Starte eine Entwicklungsumgebung deiner Wahl. Kopiere das 
Programmfragment rein, schreib eine main rundherum und spicke das 
Programm mit printf. Bei komplexeren Dingen unterteilst du die Anweisung 
in mehrere Einzelteile und lässt dir die Zwischenergebnisse auch noch 
ausgeben.

Dann lässt du es laufen und analsierst die Ausgabe in Kombination mit 
dem Programmcode.

Sorry. Aber genau so funktioniert eigenständiges lernen. Und das beste 
daran: wenn du durch bist, hast du tatsächlich etwas gelernt, was du die 
nächsten Wochen, Monate, Jahre nicht mehr vergisst und was dir bei den 
nächsten Programmen nützlich sein wird.
Millionen von C Programmierern in mehreren Generationen haben genau so 
gelernt. Und das sind heute nicht die Schlechtesten ihres Metiers. Ganz 
im Gegenteil.

Auch Radfahren kann man nicht lernen, indem man sich von anderen 
erklären lässt, wie es funktioniert. Man muss selber fahren.

Nicht von der scheinbaren Komplexität und den Sonderzeichen 
einschüchtern lassen. Das meiste ist viel einfacher als es aussieht und 
das Gefühl des 'Aha'-Erlebnisses, wenn man dann endlich durchschaut was 
da abgeht, ist unbeschreiblich.

: Bearbeitet durch User
Beitrag #5263565 wurde von einem Moderator gelöscht.
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.