Ich bin auf der Suche nach einer Resourcenschonenden Möglichkeit aus einer 'unsigned long' Variablen eine BCD Variable zu erzeugen. Im Grunde eine ltoa Anweisung würde schon reichen, jedoch bietet dies mir mein MicroC nicht an. Oder noch einfacher wäre dies zu berechnen, jedoch scheitere ich dann schon an einer dreistelligen zahl :D Bis zwei Stellen kann man ja einfach noch den HEX mit einer 6 addieren, dann hörts aber irgendwie schon auf. Jemand was parat?! Jede einzelne Stelle herrauszusubtrahieren ist wahrscheinlich nicht die feine Englische Art oder?!
Also was genau möchtest du denn jetzt? ltoa wandelt in dezimal um, aber nicht im BCD-Format (zwei Ziffern pro Byte, im high-nibble und low-nibble codiert), sondern als Zeichenkette. Hier mal ein Beispiel aus einem meiner Programme, direkt mit Ansteuerung einer 7-Segment Anzeige:
1 | void showNumber(long number) |
2 | {
|
3 | long tests[] = { 100000, 10000, 1000, 100, 10 }; |
4 | unsigned char i; |
5 | for (i = 0; i < 5; i++) { |
6 | unsigned char c = 0; |
7 | long test = tests[i]; |
8 | while (number > test) { |
9 | c++; |
10 | number -= test; |
11 | }
|
12 | ledSetDigit(i, c); |
13 | }
|
14 | ledSetDigit(5, number); |
15 | }
|
Kann man noch eleganter und kompakter schreiben. Kommt ganz drauf an, ob dein Microcontroller auch Multiplikation oder Division kann und wie schnell es sein muß. Auf einem kleinen 16fxx'er PIC, mit einigem anderen drumherum, ist das schon wieder fast zu langsam (nur maximal ein paar Hz Anzeigerate, mit Division, statt der Tabelle).
Frank Buss schrieb: > Also was genau möchtest du denn jetzt? ltoa wandelt in dezimal um, aber > nicht im BCD-Format (zwei Ziffern pro Byte, im high-nibble und > low-nibble codiert), sondern als Zeichenkette. Ja im Grunde schon, jedoch ist ja bis 1-0-0-1 je nibble das BCD Format identisch mit dem Hex Format, also eine 9 ist im Hex auch eine 9 - zumindest im Low/High Nibble. Momentan wandel ich die Daten z.b. 12345 als in ein Char Array um 1-2-3-4-5 und sende diese dann zur Anzeige/Treiber. Quasi so ähnlich wie es deine Lösung ist, (itoa macht ja im Grunde auch nichts anderes) Jedoch frage ich mich halt ob man es auch errechnen kann...
Ja, bis 9 stimmt das schon, daß das mit dem Hex-Format im Low-Nibble identisch ist. High-Nibble sehe ich jetzt nicht, da "1" im High-Nibble ja schon 16 dezimal bedeutet. Was meintest du mit 6 addieren im ersten Posting? Aber wenn du Rechenleistung zuviel hast, kannst du natürlich auch jede Ziffer direkt berechnen. Hier mal eine nicht so sinnvolle Umsetzung, aber zumindest auch mit Unterdrückung von führenden Nullen :-)
1 | char* itoaMalAnders(long value) |
2 | {
|
3 | static char buf[10]; |
4 | int i = -1; |
5 | for (int j = 8; j >= 1; j--) { |
6 | int p = (int) powf(10.0f, (float) j); |
7 | int digit = (value % p) / (p / 10); |
8 | if (i < 0) if (digit || j == 1) i++; |
9 | if (i >= 0) buf[i++] = digit + '0'; |
10 | }
|
11 | buf[i] = 0; |
12 | return buf; |
13 | }
|
> Resourcenschonenden
Willst Du den Regenwald schützen? Trinkwasser sparen? Erderwärmung
stoppen?
Du bist ein junger Mensch und hast offensichtlich eine gewisse Scheu in
der Codesammlung oder hier im Forum nach Beiträgen zu suchen die älter
als fünf Jahre sind. Da wurde das Thema schon hinreichend verkaut. Die
kürzeste Wandlungszeit betrugt 0,3761µs.
Ist es das, was Du suchst?
Falk Brunner schrieb: > Siehe Festkommaarithmetik Ist aber noch verbesserungsfähig. Warum werden die führenden Nullen nicht direkt bei der Konvertierung unterdrückt? Ein ziemliches Gemurkse, erstmal prüfen, ob das Vorzeichen da ist, dann die folgenden führenden Nullen unterdrücken und dann erst die Ziffern ausgeben. Das ganze braucht man dann auch noch redundant je nach Ausgabekanal.
@ Frank Buss (Firma: IT4 Systems GmbH & Co. KG) (foobar) >> Siehe Festkommaarithmetik >Ist aber noch verbesserungsfähig. Warum werden die führenden Nullen >nicht direkt bei der Konvertierung unterdrückt? Lies den Artikel. Ausserdem geht es um Lehrzwecke, nicht die 1001. Kopie eines ultrakompakten printf(). MFG Falk
Frank Buss schrieb: > Was meintest du mit 6 addieren im ersten > Posting? Er meint vermutlich, direkt BCD-Arithmetik. Z.B. bei der Addition zweier BCD-Zahlen muß jedes Nibble evtl. mit 6 addiert werden um eine BCD-Korrektur durchzuführen. Viele Mikrocontroller bieten einen Assembler-Behehl für die BCD-Korrektur an (für BCD Arithmetik). Das ganze in 'C' zu machen ist aber mehr als unnötig. Beispiel: 0x09 BCD 9 +0x03 BCD 3 ------ =0x0C <-- Fehler, kein BCD Wert mehr +0x06 BCD Korrektur ------ =0x12 Ergebnis wieder BCD
Wenn man Rubelus' letzten Beitrag ansieht, weiß man, dass eigentlich gar kein BCD notwendig ist. Beitrag "Mal wieder: C, AVR und das Bitshiften" Nimm Peter Daneggers Ausgaberoutine und sende jeweils 4 Bits auf einmal. Dann sparst Du Dir das kompaktieren von 2 Digits in ein Byte..
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.