Hi,
wie kann ich am schnellsten binär zu bcd wandeln (als c programm)
möglichst unabhängig. Ich mache das bisher immer so:
uint16_t Hex2Dez (uint16_t hex)
{
uint16_t dez=0;
while(hex>=10000)
{
hex-=10000;
}
while(hex>=1000)
{
dez+=0x1000;
hex-=1000;
}
while(hex>=100)
{
dez+=0x100;
hex-=100;
}
while(hex>=10)
{
dez+=0x10;
hex-=10;
}
while(hex>=1)
{
dez+=0x1;
hex-=1;
}
return dez;
}
aber ich denke es gibt besseres...
Vielen Dank für die Tips schonmal
T.
man sieht es ja auch hier:
Beitrag "32 Bit binär in BCD umwandeln"
das Modulo und Division nicht die beste Lösung für einen AVR bedeuten,
dennoch frage ich mich ob es nicht noch einfacher und schneller geht...
T.
>>Abgesehen, das hier etwas fehlt<<
was denn? ist ein 16Bit Rückgabeewert...
>>ist das eine umständliche Methode für dez = hex<<
he?
Ich meine ich hatte das Thema hier schon mal, ich werde das letzte While
nun noch in eine addierung ändern und dann sollte es passen...
T.
Hi
>Ich meine ich hatte das Thema hier schon mal, ich werde das letzte While>nun noch in eine addierung ändern und dann sollte es passen...
Dann reicht auch
while(hex>=10000)
{
hex-=10000;
}
dez = hex;
Der Rest ist überflüssig.
MfG Spess
Hey Minifloat,
das ist ja das Prinzip. Bei mir sieht es nun so aus:
uint16_t Hex2Dez (uint16_t hex)
{
uint16_t dez=0;
while(hex>=10000)
{
hex-=10000;
}
while(hex>=1000)
{
dez+=0x1000;
hex-=1000;
}
while(hex>=100)
{
dez+=0x100;
hex-=100;
}
while(hex>=10)
{
dez+=0x10;
hex-=10;
}
dez+=hex;
return dez;
}
Ich schätze schneller geht es wohl nicht. Wenn du dir das Geshifte und
Verknüpfe sparen willst, dann könnte man es auch so machen:
uint8_t itobcd(uint8_t i)
{
uint8_t dez=0
//Fehler mit unmoeglicher Zahl "von aussen" erkennbar machen
if(i > 99)
return(0xFF);
while(i>=10)
{
dez+=0x10;
i-=10;
}
//Der Rest der Division ist noch in "i",
dez+=i;
return(dez);
}
könnte das passen, naja, der Compiler macht warscheinlich eh das selbe
daraus :-)
Gruß,
T.
Hi
>hmm, ne so würde in der Variablen dez nur binär ein Wert kleiner 0x10000>stehen... oder?
Ja. Genau wie bei deinem Programm. Dezimal und Hexadezimal sind nur
verschiedene Schreibweisen. Keine verschiedenen Zahlen.
MfG Spess
spess53 schrieb:>>Ich meine ich hatte das Thema hier schon mal, ich werde das letzte While>>nun noch in eine addierung ändern und dann sollte es passen...>> Dann reicht auch>> while(hex>=10000)> {> hex-=10000;> }> dez = hex;>> Der Rest ist überflüssig.>> MfG Spess
ich denke da hast du was übersehen spess,
in den anderen whiles paasiert noch mehr ...
Sorry, habe das wohl etwas falsch benannt. Mein Code erzeugt bcds im
16Bit Wert, sieht man nur nicht auf den ersten Blick, muss ich mal
umbenennen in bintobcd oder my_itoa oder soetwas...
T.
spess53 schrieb:> Dezimal und Hexadezimal sind nur> verschiedene Schreibweisen. Keine verschiedenen Zahlen.
es geht nicht um dezimal sondern um BCD,
die Hexzahl 0x10 ist in BCD z.B. 0x16
wie kann ich mir eigentlich angucken wie die Funktion ins assembler
aussieht, beim PIC gab es da immer das "absolut Listing"....
Nutze AVR Studio und avrgcc.
T.
Ja - ha ha - man muss das Thema ja von 2 Seiten betrachten:
1)Wie schnell ist die Routine
2)Wie lang ist sie codeseitig
In diesem Fall hat sie codeseitig 252 Instruktionen, die Menge der
Ausgeführten Instruktionen hängt bei dieser Routine stark von dem
Übergabeparameter ab.
Interessant sind sicher Lösungen, die eine konstante Ausführungszeit
haben, egal was übergeben wird, wenn also wirklich gerechnet wird, die
dennoch weniger Speicherplatz benötigen.
T.
Es geht noch schneller mit Peter Danneggers Routine, die abwechselnd
subtrahiert und addiert, siehe Anhang.
i muss auf jeden Fall signed sein, kann aber auch statt long nur int
sein, dann wird es noch schneller.
bcd kann unsigned int sein, falls nur 4 Stellen gewünscht sind. Der
Startwert muss dann 65535 sein. Bei i>9999 geht die 10000er-Stelle ins
Nirwana.
Mit einer binären Suche geht es noch schneller, aber der Code ist
länger.