Hallo
kennt jemand einen Source Code um die funktion
IntToHex zu bewerkstelligen. Ich dachte dazu kann ich einiges Googeln
aber alles was ich fand war nicht so brauchbar.
Das hatte ich gefunden nur da ist amp undefiniert.
static char hex[] = { '0', '1', '2', '3', '4', '5', '6', '7',
'8', '9' ,'A', 'B', 'C', 'D', 'E', 'F' };
//The function that performs the conversion. Accepts a buffer with
"enough space" TM
//and populates it with a string of hexadecimal digits.Returns the
length in digits
int uintToHexStr(unsigned int num, char* buff)
{
int len = 0, k = 0;
do//for every 4 bits
{
//get the equivalent hex digit
buff[len] = hex[num& 0xF];
len++;
num >>= 4;
} while (num != 0);
//since we get the digits in the wrong order reverse the digits in the
buffer
for (; k<len / 2; k++)
{//xor swapping
buff[k] ^= buff[len - k - 1];
buff[len - k - 1] ^= buff[k];
buff[k] ^= buff[len - k - 1];
}
//null terminate the buffer and return the length in digits
buff[len] = '\0';
return len;
}
Gast
#5821244
Hrmf. Ersetze "&" durch "&". Dann wirds wohl gehen...
Gast
#5821426
Ohne weitere Vorgaben ist der Code denn du hast doch gar nicht so schlecht. Gerade die erste while schleife macht doch eigentlich schon das was du willst. Die for schleife würde ich umgehen indem ich vorher bswap aus den GNU Utils nutze oder was ähnliches dann stimmt auch die Byteorder wieder. Alternativ kannst du auch sicher mit snprintf und passenden format specifier was machen. Dann könnte die Lösung ein Einzeiler sein. Aber da ich mir nicht sicher bin ob es eine Hausaufgabe ist, welche du gerade versuchst zu lösen, überlasse ich Dir das googlen wie snprintf das lösen kann.
Danke ihr lieben, ich habe zwei Funktionen die ohne Problme mit C++
Builder funktionieren. Mit dem Arduino UNO
bekomme ich die richtige Länge des Strings, aber Buffer bleibt leer.
Leider kann man die Arduinos nicht debuggen.
uintToHexStr habe ich angepasst.
Der Code
static char hex[] = { '0', '1', '2', '3', '4', '5', '6', '7',
'8', '9' ,'A', 'B', 'C', 'D', 'E', 'F' };
//The function that performs the conversion. Accepts a buffer with
"enough space" TM
//and populates it with a string of hexadecimal digits.Returns the
length in digits
int uintToHexStr(unsigned int num, char* buff)
{
int len = 0, k = 0;
do//for every 4 bits
{
//get the equivalent hex digit
int tmp = num & 0xF;
buff[len] = hex[tmp];
len++;
num >>= 4;
} while (num != 0);
//since we get the digits in the wrong order reverse the digits in the
buffer
for (; k<len / 2; k++)
{//xor swapping
buff[k] ^= buff[len - k - 1];
buff[len - k - 1] ^= buff[k];
buff[k] ^= buff[len - k - 1];
}
//null terminate the buffer and return the length in digits
buff[len] = '\0';
return len;
}
unsigned int num_hex_digits(unsigned int n) {
int ret = 0;
while (n) {
n >>= 4;
++ret;
}
return ret;
}
int IntToHex(uint32_t num, char* buffer)
{
char *p = buffer;
uint32_t pad = 0;
uint32_t len = num_hex_digits(num);
/* if odd number, add 1 - zero pad number */
if (len % 2 != 0)
pad = 1;
/* move to end of number string */
p += len + pad; //- 1;
len = 0;
*p = 0;
*p--;
while (num) {
len++;
int tmp = num & 0xF;
if (tmp < 10)
*p = tmp + '0';
else
*p = tmp + 'A' - 10;
Serial.print("++++>");
Serial.print(*p);
num >>= 4;
p--;
}
if (pad) {
*p = '0';
}
return (len);
}
char Buffer[10];
uint32_t hex = 0x7988aa;
uintToHexStr(hex, Buffer);
Serial.print("Hex Test ");
Serial.println(Buffer);
Gast
#5821609
Warum nicht einfach
1 | |
https://www.arduino.cc/reference/en/language/functions/communication/serial/print/ oder
1 | |
https://www.arduino.cc/en/Tutorial/StringConstructors
Hallo das Problem war das unsigned int eine 16 bit integer ist und ich
eine 32 bit zahl auflösen wollte.
so funktioniert das auch mit einem uno
static char hex[] = { '0', '1', '2', '3', '4', '5', '6', '7',
'8', '9' ,'A', 'B', 'C', 'D', 'E', 'F' };
//The function that performs the conversion. Accepts a buffer with
"enough space" TM
//and populates it with a string of hexadecimal digits.Returns the
length in digits
int uintToHexStr(uint32_t num, char* buff)
{
int len = 0, k = 0;
do//for every 4 bits
{
//get the equivalent hex digit
uint32_t tmp = num & 0xF;
buff[len] = hex[tmp];
len++;
num >>= 4;
} while (num != 0);
//since we get the digits in the wrong order reverse the digits in the
buffer
for (; k<len / 2; k++)
{//xor swapping
buff[k] ^= buff[len - k - 1];
buff[len - k - 1] ^= buff[k];
buff[k] ^= buff[len - k - 1];
}
//null terminate the buffer and return the length in digits
buff[len] = '\0';
return len;
}
Martin M. schrieb: > //since we get the digits in the wrong order reverse the digits in the > buffer Wie wäre es, die "digits" einfach gleich in der richtigen Reihenfolge anzuordnen?
Gast
#5821656
Rufus Τ. F. schrieb: > Wie wäre es, die "digits" einfach gleich in der richtigen Reihenfolge > anzuordnen? Wäre zu einfach, außerdem kann man dann den "tollen" XOR Trick nicht zeigen :-)
Gast
#5821657
Rufus Τ. F. schrieb: > Wie wäre es, die "digits" einfach gleich in der richtigen Reihenfolge > anzuordnen? Dazu muss man aber wissen, wie viele Ziffern es sind, oder vorher Platz lassen. Folgendermaßen könnte man die Ziffern vorab zählen:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
45 | |
46 | |
47 | |
48 | |
49 | |
50 | |
51 | |
52 | |
53 | |
54 | |
55 | |
56 | |
57 | |
58 | |
59 | |
60 | |
61 | |
62 | |
Implementiert via templates, sodass es direkt für alle Integer-Typen funktioniert. Diese müssen aber vorzeichenlos sein. Dafür ist es so etwas effizienter und sicherer durch eingebaute Array-Bereichs-Prüfung. Funktioniert nur auf AVR-GCC und Arduino leider nicht, weil es da keine C++ Standard Bibliothek gibt.
Gast
#5821672
@Dr.Sommer : Waruuum?
Gast
#5821679
Für Controller mit effektivem Bitshifting(barrel shifter): Leftshift anstelle von Rightshift Höchtes Nibble runterholen mit >> (sizeof Zahl * 8 -4) ,.. and 0xf wenn Null, nicht in String einfügen, ansonst normal von links weg einfügen
Gast
#5821693
Deine Hex-Darstellung wird ja in einem String gespeichert. Oben wurde schon erwähnt, dass du diese Funktion evtl. gar nicht brauchst. imonbln schrieb: > Alternativ kannst du auch sicher mit snprintf und passenden format > specifier was machen. Dann könnte die Lösung ein Einzeiler sein. Ich weiß nicht was Arduino Uno so alles kann, aber C kann jede dezimale Zahl in oktaler/hexadezimaler Darstellung problemlos darstellen. Bsp.:
1 | |
2 | |
Oder halt mit snprintf in einem String ablegen
Gast
#5821719
Ich hätte auch snprintf verwendet.
was ich im ganzen thread nicht gefunden habe ist eine (m.e. durchaus sinnvolle/wichtige) information: wozu? da das ganze unter pc programmierung gepostet ist, nehme ich mal an es handelt sich um eine plattform mit etwas mehr cojones als ein arduino (wurscht ob mini, nano, uno, ...)
Dr. Sommer schrieb: > Dazu muss man aber wissen, wie viele Ziffern es sind, Es ist recht üblich, Hexwerte mit führenden Nullen auszugeben. Und dann ist die Anzahl der Stellen implizit gegeben.
Danke für die netten Antworten.
Leider geht das alles nicht was vorgeschlagen wurde Arduino UNO sprintf
verarbeitet nur 16 bit Integer was größer ist wird abgeschnitten.
static char hex[] = { '0', '1', '2', '3', '4', '5', '6', '7',
'8', '9' ,'A', 'B', 'C', 'D', 'E', 'F' };
//The function that performs the conversion. Accepts a buffer with
"enough space" TM
//and populates it with a string of hexadecimal digits.Returns the
length in digits
int Int2Hex(uint32_t num, char* buff)
{
int len = 0, k = 0;
do//for every 4 bits
{
//get the equivalent hex digit
uint32_t tmp = num & 0xF;
buff[len] = hex[tmp];
len++;
num >>= 4;
} while (num != 0);
//since we get the digits in the wrong order reverse the digits in the
buffer
for (; k<len / 2; k++)
{//xor swapping
buff[k] ^= buff[len - k - 1];
buff[len - k - 1] ^= buff[k];
buff[k] ^= buff[len - k - 1];
}
//null terminate the buffer and return the length in digits
buff[len] = '\0';
return len;
}
Hierbei ist der uint32_t Teil wichtig.
Gast
#5828502
Martin M. schrieb: > Leider geht das alles nicht was vorgeschlagen wurde Arduino UNO sprintf > verarbeitet nur 16 bit Integer was größer ist wird abgeschnitten. na vermutlich wegen %d als format spezifier. Bei den Datentypen aus inttypes.h sollte man auch dazugehörige Makros (für die Eingabe/Ausgabe) benutzen (und nicht %d, %x usw..)
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
Aber so ist es bestimmt noch einfacher und richtiger. Dr. Sommer schrieb: > Warum nicht einfachSerial.print(78, HEX); > https://www.arduino.cc/reference/en/language/functions/communication/serial/print/ > > oder > String stringOne = String(45, HEX); > https://www.arduino.cc/en/Tutorial/StringConstructors
Also die Function die ich gepostet habe die funktioniert ohne Probleme beim 8 bit UNO muss man einiges beachten der kann auch kein Float ausgeben mit %f in printf oder sprintf da macht man es mit dtostrf Beitrag "dtostrf funktion allgemein" oder auch die Variablen. In PC C++ soll man nach Möglichkeit nur lokale Vars benutzen. Mit µMCU ist speicher ein hares gut und man muss Sparsam damit umgehen, so definiert man z.B. ein Text Buffer global char Buffer[50]. Mehr Fallstricke fallen mir nicht ein währe vielleicht Sinnvoll in einem anderen Post. Ein schönes Wochenende.
Gast
#5830345
Martin M. schrieb: > Das hatte ich gefunden nur da ist amp undefiniert. Das kommt davon, wenn man HTML-Texte kopiert.
Gast
#5833224
Martin M. schrieb: > Ich dachte dazu kann ich einiges Googeln > aber alles was ich fand war nicht so brauchbar. Ach herrje, da hättest du besser dir die steinalte Lernbetty hier im Forum heruntergeladen. Hier mal ein Auszug:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
So, reicht's? Und wie man den ganzen Schmonzes in einen Puffer schreibt und dann die Länge oder nen Zeiger auf das folgende Nullbyte zurückliefert, überlasse ich dem TO als Fingerübung. Und warum HexQ_Out hier einen Pointer anstelle des Values haben will, darf bei Bedarf ergrübelt werden. Stichwort SVC. Manchmal frag ich mich, wieso Aufgaben dieses Levels eine verzweifelte Suche im Internet erforderlich machen. W.S.
Gast
#5833236
Dr. Sommer schrieb: > Dazu muss man aber wissen, wie viele Ziffern es sind, Ach, noch nie von der RBI/RBO-Funkionalität gehört? Also Hardware kannst du auch nicht. Nee, das Einfachste - sofern man sowas tatsächlich will (was ich bezweifle, das hat Rufus schon richtig zum Ausdruck gebracht) wäre, solange die auszugebenden Zeichen zu ignorieren, bis eines ungleich '0' kommt oder die Einerstelle erreicht ist. Eben RBI/RBO in Software. W.S.
Gast
#5833458
W.S. schrieb: > Ach, noch nie von der RBI/RBO-Funkionalität gehört? Also Hardware kannst > du auch nicht. Wo ging es in diesem Thread um Hardware? W.S. schrieb: > solange die auszugebenden Zeichen zu ignorieren, bis eines ungleich '0' > kommt oder die Einerstelle erreicht ist. Was aber nur geht, wenn man die Zeichen von links an produzieren kann. Was nur effizient geht, wenn man einen Barrel-Shifter hat (Mr. Hardware). Was aber auch schon alles gesagt wurde. Was passiert eigentlich wenn man deine supertollen Code auf einer Plattform mit long=64 bit ausführt? Warum benutzt du auf ARM die unsägliche Windows-Nomenklatur mit word=16bit, wo ARM das schon ewig als 32bit festlegt? W.S. schrieb: > Stichwort SVC. Hast du im Ernst eine Reihe an Hex-Ausgabefunktionen als Syscall implementiert? Es aber nicht geschafft dabei mehr als ein 32bit-Word als Parameter zu übergeben? Mindestens 4 sollte man hinbekommen. Mehr auch mit etwas Stack-Pointer-Gymnastik.
Gast
#5833598
Für die Lästernden, hier eine Version welche von links an ausgibt und daher ohne Barrel-Shifter ineffizient ist:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
45 | |
46 | |
47 | |
48 | |
49 | |
50 | |
51 | |
52 | |
53 | |
54 | |
Funktioniert auch wieder dank Templates mit allen Integer-Typen auf allen Plattformen (solange die Größe ein Vielfaches von 4bit ist; für krumme Längen bräuchte es mehr Fallunterscheidungen). Es kann die Mindest-Länge der Ausgabe angegeben werden. Zusätzlich erfolgt die Ausgabe über einen Output-Iterator. Der Aufrufer kann also selbst festlegen, ob in einen Puffer oder direkt in einen Output-Stream geschrieben werden soll. Als Beispiel wird in einen char-Buffer, direkt auf std::cout und einen Beispiel-Dummy-UART-Output geschrieben.
Gast
#5834063
Dr. Sommer schrieb: > Hast du im Ernst eine Reihe an Hex-Ausgabefunktionen als Syscall > implementiert? Es aber nicht geschafft dabei mehr als ein 32bit-Word als > Parameter zu übergeben? Mindestens 4 sollte man hinbekommen. Mehr auch > mit etwas Stack-Pointer-Gymnastik. Hast du im Ernst schon jemals einen ARM7TDMI aus der Nähe gesehen? Nö, haste nicht. Und das verstehende Lesen scheint dir auch nicht sympathisch zu sein. W.S.
Gast
#5834081
W.S. schrieb: > Hast du im Ernst schon jemals einen ARM7TDMI aus der Nähe gesehen? Selbst wenn nicht, hätte ich trotzdem Recht. Die "SVC"-Instruktion verändert nicht die Inhalte der 13 General-Purpose-Register, welche man somit zur Parameter-Übergabe nutzen kann. Eine Int2Hex-Funktion ist eine allgemeine datenverarbeitende Hilfsfunktion und gehört nicht in einen Syscall. Alles was als Userspace-Funktion implementiert werden kann, sollte das auch, ggf. in einer Library. Dies trennt die OS-Teile vom Anwendungsteil. Du kannst deinen Funktionen anscheinend nichtmal übergeben, auf welchen Dateideskriptor oder Hardware die Ausgabe erfolgen soll; du hast hier die völlig unabhängigen Dinge "V24-Ausgabe" und "Int2Hex" miteinander verknüpft, sodass man sie nicht mehr getrennt nutzen kann. Ganz schlechtes Design. Linux macht vor wie das richtig geht: Ein "write"-Syscall welcher einen beliebigen Puffer ausgibt, und komfortable Formatierungsfunktionen wie printf in der C-Library. Da Syscalls ein extra Overhead sind (insbesondere auf Systemen mit virtuellem Speicher/MMU) sollte man möglichst viele Daten mit einem Aufruf übergeben, und nicht jeden Integer einzeln. W.S. schrieb: > Und das verstehende Lesen scheint dir auch nicht sympathisch zu sein. Du bist doch der, welcher trotz wiederholter Versuche nichts dazulernt. Wie war das mit dem mehrdimensionalen Array?
Gast
#5835744
Dr. Sommer schrieb: > Selbst wenn nicht, hätte ich trotzdem Recht. Die "SVC"-Instruktion > verändert nicht die Inhalte der 13 General-Purpose-Register, welche > man somit zur Parameter-Übergabe nutzen kann. Aha, du kennst also auch nichts von sowas wie einem ABI, also den Aufruf-Konventionen für die betreffende Plattform. W.S.
Gast
#5835786
W.S. schrieb: > Aha, du kennst also auch nichts von sowas wie einem ABI, also den > Aufruf-Konventionen für die betreffende Plattform. Der AAPCS, das ABI für ARM, benutzt 4 Register r0-r3 für die Parameter Übergabe. Also 4 32bit-Words. Mehr Words kann man auf dem Stack übergeben. Also, warum nochmal kannst du nur ein Word per SVC übergeben?
Gast
#5835789
PS: Und warum muss man sich bei SVC an das normale ABI halten? Selbst Linux nutzt hier mehr als 4 Register für mehr Parameter.
Dr. Sommer schrieb: > Warum benutzt du auf ARM die > unsägliche Windows-Nomenklatur mit word=16bit, wo ARM das schon ewig als > 32bit festlegt? Ach Gottchen. Dann ersetzt man eben word durch uint16_t und long durch uint32_t usw. Dafür sind die types ja da. Die Methode von W.S. jedenfalls benutze ich auch seit Jahren ohne Problem auf STM32, AVR, 8051, PIC usw. Nechteilig finde ich nur, das die Tabelle auf manchen Plattformen im RAM liegen muss. Aber wer heute keine 16 Bytes mehr frei hat, der hat auch noch andere Probleme.
Gast
#5835973
Matthias S. schrieb: > Ach Gottchen. Dann ersetzt man eben word durch uint16_t und long durch > uint32_t usw. Dafür sind die types ja da. Sollte man halt auch machen anstatt dieses Pascal-in-C zu verbreiten...
So kann mans auch machen:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
der 3. Parameter ist die Länge des Puffers in char. Die Funktion gibt einen Zeiger auf den Ergebnis-Puffer zurück, wenn die Zahl gewandelt werden konnte und NULL, wenn der Puffer für die Wandlung zu kurz war.
Gast
#5837969
und warum lässt ihr immer das Präfix "0x" weg?
zitter_ned_aso schrieb: > und warum lässt ihr immer das Präfix "0x" weg? weil das nicht immer nötig ist. weil das nur eine Notation von C ist (es gibt auch andere) weil man es auch einfach davor extra ausgeben kann
Gast
#5838351
Dirk B. schrieb: > zitter_ned_aso schrieb: >> und warum lässt ihr immer das Präfix "0x" weg? > > weil das nicht immer nötig ist. > weil das nur eine Notation von C ist (es gibt auch andere) > weil man es auch einfach davor extra ausgeben kann Das hat überhaupt nichts mit Notation zu tun. mit 0x werden hexadezimale Zahlen gekennzeichnet. Da kann man auch nichts extra ausgeben. Da in den obigen Beispielen nur Zahlen von 0..9 benutzt werden muß es nicht hexadezimal sein, da bekanntlich bis zur Ziffer 9 dezimal und hexadezimal identisch sind. Allerdings gehört es nach meinem Verständnis zum guten (Programmier)Stil, das man es in einem Quelltext einheitlich macht. An Stelle von 0x0f hätte Uhu dann auch 15 schreiben sollen.
Zeno schrieb: > An > Stelle von 0x0f hätte Uhu dann auch 15 schreiben sollen. Das macht m.E. aber die Maskierung des Nibbles deutlicher, als wenn du 15 schreibst.
Gast
#5838407
Matthias S. schrieb: > Zeno schrieb: >> An >> Stelle von 0x0f hätte Uhu dann auch 15 schreiben sollen. > > Das macht m.E. aber die Maskierung des Nibbles deutlicher, als wenn du > 15 schreibst. Ich wollte eigentlich nur ausdrücken, das ich es in einem Quelltext einheitlich machen würde. Also alles wo es um Bit oder Byteoperationen geht würde ich dann einheitlich als Hex schreiben alles andere im gewohnten Dezimalsystem. Letztendlich ist das aber völlig Rille, es soll jeder so schreiben wie es ihm angenehm ist und da ist es eben wurscht ob ich 0xff oder 255 oder 0377 oder 0b11111111 schreibe. Es ist immer die gleiche Zahl, die Frage ist halt nur was am Ende lesbarer ist.
Gast
#5838410
Zeno schrieb: > Da in den obigen Beispielen nur Zahlen von 0..9 benutzt werden muß es > nicht hexadezimal sein, da bekanntlich bis zur Ziffer 9 dezimal und > hexadezimal identisch sind. Dachte ich auch beim ersten Hingucken aber hinterher kommt ein +7 damit springt er von der 9 zum A ;)
Gast
#5838535
Gurgl schrieb: > Dachte ich auch beim ersten Hingucken aber hinterher kommt ein +7 damit > springt er von der 9 zum A ;) Das A kommt aber in dem Quelltext nicht "optisch" vor, soll heisen man sieht es nicht im Quelltext. Sein Code hat aber einen kleinen Fehler. Die Zeile if (len <= 2) muß richtigerweise if (len <= 1) heißen. Ansonsten wird bei einem zu groß gewählten Puffer ein Leerstring ausgegeben. Beispiel mit Puffergröße 3: num=15 müßte 'F' ergeben ergibt aber Leerstring num=16 ergibt korrekt '10' Je größer Puffer wird um so extremer wird das Verhalten
Gast
#5838560
Grad noch mal getestet, es geht trotzdem nicht. Die 2 sind schon korrekt wegen dem '\0' Zeichen. Man muß den Puffer vorher mit dem Zeichen '0' initialisieren, wenn man ein halbwegs brauchbares Ergebnis haben will.
Matthias S. schrieb: > Zeno schrieb: >> An >> Stelle von 0x0f hätte Uhu dann auch 15 schreiben sollen. > > Das macht m.E. aber die Maskierung des Nibbles deutlicher, als wenn du > 15 schreibst. So ist es…
Zeno schrieb: > Das A kommt aber in dem Quelltext nicht "optisch" vor, soll heisen man > sieht es nicht im Quelltext. Als erfahrener Programmierer weiß man, dass ASCII '9' + 7 == 'A' ist… Das ist ein uralter Trick aus den Zeiten, in denen noch fast alles in ASM programmiert wurde.
Zeno schrieb: > Grad noch mal getestet, es geht trotzdem nicht. Da hast du wohl einen kleinen Fehler gemacht: Ergebnis ist nicht die Variable buff, sondern der Pointer, den uintToHexStr zurück gibt. Der zeigt je nach Länge von Buff und Größe der Zahl irgendwo in buff hinein. Was davor steht, interessiert nicht. Die Routine hat zudem noch einen Vorteil: sie schreibt nichts kaputt, wenn der Puffer zu klein ist. Nebenbei: Nach demselben Prinzip kann man eine Zahl auch ins Dezimalsystem wandeln. Statt num & 0x0f muss man dann eben num % 10 schreiben und statt num >>= 4; num /= 10;. Der Trick mit dem + 7 kann dann natürlich entfallen. Die Anweisung
1 | |
2 | |
kann man natürlich auch so schreiben:
1 | |
2 | |
und wenn man statt 'A' 'a' schreibt, kommt das Ergebnis in Kleinbuchstaben… Diese Schreibweise hat den Vorteil, dass der Code auch in anderen (gängigen) Zeichencodierungen funktioniert. Den Ausdruck 'A' - '9' berechnet der Compiler und setzt dafür die Konstante 7 ein.
Uhu U. schrieb: > Den Ausdruck 'A' - '9' berechnet der Compiler und setzt dafür > die Konstante 7 ein. Vorteil ist vor allem die bessere Lesbarkeit. Und man kann es auch in Assembler verwenden, die unterstützen solche einfachen Ausdrücke auch.
Gast
#5838661
> template <typename T> > std::size_t leadingZeroes (T x) { > std::size_t c = 0; > while ((x & (T { 1 } << (std::numeric_limits<T>::digits - 1))) == 0) { x > <<= 1; ++c; } > return c; > } Wenn ich diesen CPP-Murx sehe, wird mir schlecht. Das verbraucht ja selbet im hässlichem PIC-Assembler weniger Zeichen und ist aussagekräftiger.
Dr. Sommer schrieb: > Für die Lästernden, hier eine Version welche von links an ausgibt und > daher ohne Barrel-Shifter ineffizient ist: Uhu U. schrieb: > So kann mans auch machen:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
bzw.
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
Beitrag #5838675 wurde von einem Moderator gelöscht.
Gast
#5838690
PIClig schrieb: > Wenn ich diesen CPP-Murx sehe, wird mir schlecht. Ja, der C PräProzessor ist schlimm. Das ist aber C++. PIClig schrieb: > Das verbraucht ja selbet im hässlichem PIC-Assembler weniger Zeichen > und ist aussagekräftiger. Auch für sämtlich Integer-Typen und Plattformen? Wohl kaum. Michael B. schrieb: >> So kann mans auch machen: Da das nicht Tail-Rekursiv ist - können Optimizer das iterativ umbauen?
Dr. Sommer schrieb: > Da das nicht Tail-Rekursiv ist - können Optimizer das iterativ umbauen? Vermutlich nicht, aber kann sowas ja auch iterativ programmieren… Man muss eben ein f von links nach rechts drüber schieben und mit & die betreffende Tetrade heraus picken, die man dann entsprechend nach rechts schiebt…
Gast
#5838709
Uhu U. schrieb: > Man > muss eben ein f von links nach rechts drüber schieben und mit & die > betreffende Tetrade heraus picken, die man dann entsprechend nach rechts > schiebt… Dann muss man aber doppelt shiften - sowohl das "f", und jedes mal das gewünschte Nibble nach Rechts. Ohne Barrelshifter eher blöd. Besser ist es, den Wert selbst kontinuierlich weiter zu shiften.
Dr. Sommer schrieb: > Dann muss man aber doppelt shiften - sowohl das "f", und jedes mal das > gewünschte Nibble nach Rechts. Ohne Barrelshifter eher blöd. Wir sind hier im "Forum: PC-Programmierung" - PC-Prozessoren haben Barrelshifter…
Gast
#5838931
Uhu U. schrieb: > Als erfahrener Programmierer weiß man, dass ASCII '9' + 7 == 'A' Das habe ich ja nicht bezweifelt das dem so ist. Uhu U. schrieb: > Zeno schrieb: >> Grad noch mal getestet, es geht trotzdem nicht. > > Da hast du wohl einen kleinen Fehler gemacht: Stimmt! Ich hatte mir nur den Puffer angeschaut und nicht das Ergebnis der Funktion. Sorry war mein Fehler.
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.