Hexadezimalen String in DEC Integer konvertieren

Werni:
Mh, jetzt seh ich auch man hätte das erste Byte weglassen können -.-
Geht es denn jetzt?

Ja, dann gehts.

Irgendwas in der Art:

char in[] = "00CCA7F6";
int out = 0;
for (byte t=0; t<8; t++) {
  if (in[t]>='0' && in[t]<='9')
    in[t] -= '0';
  if (in[t]>='A' && in[t]<='F')
    in[t] -= 'A'-10;
  out = out*10 + in[t];
}

Ungetestet, also ohne Gewähr! :wink:

Das basiert auf dem ASCII-Alphabet und den Positionen der Buchstaben darin.

Per XOR, nach dem was da steht.

Oh Man, das war einfach :roll_eyes:

Hi Joghurt,
es funktioniert leider nicht.

Heraus kommt 20136. Es sollte aber 13412342 sein

Wie gesagt hab ichs nicht getestet, geht hier in der Firma nicht, Du wirst es wohl debuggen müssen. :frowning:

Guck Dir mal Serial.begin und Serial.println and, damit kannst Du Dir Werte auf die Konsole ausgeben lassen.
Damit solltest Du rausbekommen können wos hakt.

Mach ich schon die ganze Zeit

void setup(){
  Serial.begin(9600);
  char in[] = "00CCA7F6";
  int out = 0;
  for (byte t=0; t<8; t++) {
    if (in[t]>='0' && in[t]<='9')
      in[t] -= '0';
    if (in[t]>='A' && in[t]<='F')
      in[t] -= 'A'-10;
    out = out*10 + in[t];
  }
  Serial.println(out);
}

Ich weiß nicht genau wo ich da debuggen soll.
Für mich erscheint der Code komplett richtig.

Ach, ich doof! :slight_smile:

Mach statt

out = out*10 + in[t];
out = out*16 + in[t];

und out sollte zur sicherheit eine unsigned int sein...

Hi Joghurt,
das hatte ich schon ausprobiert. Es funktioniert nicht.
Da kommt 42998 raus.

ist *10 nicht eigentlich richtig, damit die neue Zahl einfach um eins nach rechts verschoben wird?

Werni:
ist *10 nicht eigentlich richtig, damit die neue Zahl einfach um eins nach rechts verschoben wird?

Nein, weil in jedem Hex-Zeichen ja die Information von vier Bit, also 16, steht. :slight_smile:

Probier mal zwecks debugging folgendes:

void setup(){
  Serial.begin(9600);
  char in[] = "00CCA7F6";
  unsigned int out = 0;
  for (byte t=0; t<8; t++) {
    if (in[t]>='0' && in[t]<='9') {
      Serial.println(in[t]);
      in[t] -= '0';
      Serial.println(in[t], DEC);
    }
    if (in[t]>='A' && in[t]<='F') {
      Serial.println(in[t]);
      in[t] -= 'A'-10;
      Serial.println(in[t], DEC);
    }
    Serial.println(out);
    out = out*10 + in[t];
  }
  Serial.println(out);
}

So ähnlich hatte ich das schon gemacht:

void setup(){  
  Serial.begin(9600);
  char in[] = "00CCA7F6";
  unsigned int out = 0;
  
  for (byte t=0; t<8; t++) {
    Serial.print(in[t]);
    Serial.print(": ");
    
    if (in[t]>='0' && in[t]<='9')
      in[t] -= '0';
    if (in[t]>='A' && in[t]<='F')
      in[t] -= 'A'-10;
    int j=0;
    if (in[t] >= 10)
      j=1;
    //for (j; j<t+1; j++){
    //  Serial.print(" ");
    //}
    Serial.print(in[t], DEC);
    Serial.print("     ");
    if (in[t]<10) Serial.print(" ");
    Serial.println(out);
    //Serial.print("neu:");
    //Serial.println(out);
    out = out*16 + in[t];
  }
  Serial.println(out);
}

0: 0 0
0: 0 0
C: 12 0
C: 12 12
A: 10 204
7: 7 3274
F: 15 52391
6: 6 51839
42998

Komisch, dass der Wert am Ende kleiner wird

Werni:
7: 7 3274
F: 15 52391
6: 6 51839
42998

Mooment! Der zeigt Dir hier anscheinend eine int, keine long! :slight_smile:

Probier mal bei der abschließenden Ausgabe:

Serial.print(out>>16);
Serial.println(out&0xffff);

Hey Joghurt,
ich hab ein bisschen recherchiert und folgendes draus gemacht:

void setup() {
  Serial.begin(9600);
  char in[] = "00CCA7F6";
  
  
  //To DEZ
  int Zahlensystem = 16;
  int length = sizeof(in)-1;
  long out = 0;
  char newIn[length];
  for (byte t=0; t < length; t++) {
    Serial.print(in[t]); Serial.print("  ");
    if (in[t]>='0' && in[t]<='9')
      in[t] -= '0';
    if (in[t]>='A' && in[t]<='F')
      in[t] -= 'A'-10;
    if (in[t]<10) Serial.print(" ");
    Serial.print(in[t], DEC); Serial.print(" * 16^");
    out += in[t] * pow(Zahlensystem, length - t - 1);
    Serial.print(length - t - 1, DEC);
    Serial.print(" = ");
    Serial.println(in[t] * pow(Zahlensystem, length - t - 1));
  }
  Serial.println("------------");
  Serial.println(out, DEC);
}

Heraus kommt dann:

0 0 * 16^7 = 0.00
0 0 * 16^6 = 0.00
C 12 * 16^5 = 12582896.00
C 12 * 16^4 = 786431.43
A 10 * 16^3 = 40959.97
7 7 * 16^2 = 1792.00
F 15 * 16^1 = 240.00
6 6 * 16^0 = 6.00

13412325

Sollwert: 13412342

Der Arduino macht wohl Rundungsgehler :frowning:

Das ist vermutlich das pow(), das ist leider nicht 100%ig... :frowning:

Bei so einer Umrechnung hat Pow() absolut nichts verloren.

Anstelle von
out += in[t] * pow(Zahlensystem, length - t - 1);
schreibst Du entweder
out = out * 16 + in[t];
oder am besten gleich
out = out << 4 + in[t];

Da ja in[t] immer ein Nibble (4 Bit) ist, ist das letzte Beispiel nicht nur das schnellste sondern eigentlich auch das verständlichste. Du verschiebst das bisherige Ergebnis um 4 Bit nach links und machst somit Platz für die nächsten 4 Bit.

Hi MaFu,
out = out << 4 + in[t];
hat nicht funktioniert.
*16 aber schon.
Jetzt funktionert es.
Vielen Dank euch beiden,

Grüße
Werni

Von String mit Hex zu long:

#include <stdlib.h>

void setup()
{
  // anderer code hier
  char in[] = "00CCA7F6";
  long  out = strtol(in, NULL, 16);
  // anderer code hier
}

Na toll -.-
und ich hab mich schon darüber aufgeregt, dass es nicht wie überall sonst eine Funktion dafür gibt.

So richtig schön zum spielen hat das jemand hier gemacht:

http://www.arndt-bruenner.de/mathe/scripts/Zahlensysteme.htm

Werni:
Hi MaFu,
out = out << 4 + in[t];
hat nicht funktioniert.
*16 aber schon.
Jetzt funktionert es.
Vielen Dank euch beiden,

Grüße
Werni

War für mich wohl noch zu früh am Morgen.
Der Shift-Operator hat eine niedrigere Rangfolge, es muss also so lauten:
out = (out << 4) + in[t];

Also zum mitschreiben wäre das hier die Lösung???

void setup() {
  Serial.begin(9600);
  char in[] = "00CCA7F6";
  
  
  //To DEZ
  int Zahlensystem = 16;
  int length = sizeof(in)-1;
  long out = 0;
  char newIn[length];
  for (byte t=0; t < length; t++) {
    Serial.print(in[t]); Serial.print("  ");
    if (in[t]>='0' && in[t]<='9')
      in[t] -= '0';
    if (in[t]>='A' && in[t]<='F')
      in[t] -= 'A'-10;
    if (in[t]<10) Serial.print(" ");
    Serial.print(in[t], DEC); Serial.print(" * 16^");
    out = (out << 4) + in[t];
    Serial.print(length - t - 1, DEC);
    Serial.print(" = ");
    Serial.println(in[t] * pow(Zahlensystem, length - t - 1));
  }
  Serial.println("------------");
  Serial.println(out, DEC);
}