Hallo,
ich möchte gerne einige Zahlen in bestimmte Zahlenformate (bin, dec,
hex) umwandeln und über uart rüberschicken.
Wie kann ich am besten dass so machen, dass ich "0b" voranstelle.
Das "Problem" ist, dass wenn ich mache,
wird der string prefix unnötig lang. Geplant ist alles in
buffer_int_conv auszulagern. Dieses habe ich entsprechend groß angelegt,
dann +prefix binäre Zahlen vom Typ int16_t reinpassen.
2x puts hintereinander geht nicht, da puts den String mit einem
zusätzlichen '\n' ausgibt. Dann hättest Du nach dem "0b" zusätzlich ein
'\n'.
Wie wärs damit:
void put_bin(int16_t value)
{
char buffer[18];
putchar('0');
putchar('b');
puts(itoa(value, buffer, 2));
}
Frank M. schrieb:> 2x puts hintereinander geht nicht, da puts den String mit einem> zusätzlichen '\n' ausgibt.
Ach, Mist, das hatte ich übersehen.
Alternative (so die Laufzeitumgebung das hergibt)
fputs.
Das nämlich macht's nicht.
Helmut Lenzen schrieb:> Oder ganz einfach ein printf / sprintf verwenden.
Tja, wenn das verflixte printf auch die Ausgabe einer Zahl im
Bionärformat erlauben würde. Tut es aber nicht. ;-)
Okay, das ginge:
void put_bin(int16_t value)
{
char buffer[18];
printf("0b%s\n", itoa(value, buffer, 2));
}
Ist bisher die kürzeste Version. Aber bestimmt nicht die eleganteste. Da
kommt es auf die Zielplattform an. Wird printf() unterstützt? Gibt es
ein stdout für fputs()? Fragen über Fragen...
Und hier die schnellste, die ohne itoa(), printf() und fputs() - und vor
allem ohne Buffer auskommt:
1
voidput_bin(uint16_tvalue)
2
{
3
uint16_ti=0x8000;
4
5
putchar('0');
6
putchar('b');
7
8
while(i)
9
{
10
if(value&i)
11
{
12
putchar('1');
13
}
14
else
15
{
16
putchar('0');
17
}
18
value&=~i;
19
i>>=1;
20
}
21
putchar('\n');
22
}
Ich habe den Parameter übrigens von int16_t auf uint16_t geändert.
Negative Binärzahlen finde ich nicht wirklich sinnvoll.
Nachteil der obigen Funktion: Es werden alle führenden Nullen gedruckt.
Die könnte man noch mit einem Flag unterdrücken.... wenn man es denn
will.
Und weil es soviel Spaß macht, hier noch die obligatorische rekursive
Methode:
1
staticvoidput_bin2(uint16_tvalue)
2
{
3
if(!value)
4
{
5
return;
6
}
7
put_bin2(value>>1);
8
putchar('0'+(value&1));
9
}
10
11
voidput_bin(uint16_tvalue)
12
{
13
putchar('0');
14
putchar('b');
15
16
if(!value)
17
{
18
putchar('0');
19
}
20
else
21
{
22
put_bin2(value);
23
}
24
putchar('\n');
25
}
Diese kommt auch ohne Buffer aus, benutzt lediglich putchar() und
unterdrückt sogar führende Nullen. Leider muss das ganze wegen des
abschließenden '\n' in 2 Funktionen realisiert werden. Ohne
Zeilenabschluss hätte eine Funktion als Konvertierungsfunktion gereicht.
Das führende '0b' hätte man noch in die Abbruchbedingung der Rekursion
mit reinnehmen können.
Peter Dannegger schrieb:> Auf dem AVR gulpt das ebenmal satte 64 Byte Stack.
Ja, irgendwo muss der nicht mehr notwendige Buffer ja versteckt werden
;-)
Das Ding würde ich auch niemals einsetzen. Das war ein rein
theoretischer Ansatz mit der Rekursion als pures Spielzeug.