Hallo, Ich baue mir gerade einen Frequenzzähler und habe den Wert der Frequenz in Hertz in einer Variablen: unsigned long int hertz=123456789; // Zum beispiel ;) So nun stellt sich mir die Frage wie ich es am besten in Mhz auf dem display darstelle. AVR sind ja nicht für Flieskomma-Arithmetik ausgelegt und deswegen würde hertz/1000000 erstens ewig dauern, und zweitens würde sprintf mit Flieskommazahlen auch ewig brauchen. Gibt es eine schnelle vernünftige Lösung um nicht unnötig komplexe Flieskommaoperationen durchzuführen nur um den Wert darzustellen?
Die einfachste Lösung: Vor die 6. Stelle (von rechts aus gesehen) einfach das Komma auf dem Display setzen.
>AVR sind ja nicht für Flieskomma-Arithmetik ausgelegt und deswegen würde >hertz/1000000 erstens ewig dauern, und zweitens würde sprintf mit >Flieskommazahlen auch ewig brauchen. Was ist bei dir ewig? Eine Ausgabe auf LCD braucht länger als die Umrechnung mit float und Stringwandlung mit sprintf. Was bitte schön dauert da zu lange?
Cagara wrote: > AVR sind ja nicht für Flieskomma-Arithmetik ausgelegt und deswegen würde > hertz/1000000 erstens ewig dauern, Hängt ein bischen davon ab, was für dirch "ewig" ist. > und zweitens würde sprintf mit > Flieskommazahlen auch ewig brauchen. Wetten dass der Controller schneller rechnet als du auf's Display gucken kannst? Ist aber nicht nötig. Nimm itoa/sprintf mit integer und verwurste den erzeugten String entsprechend.
Die Frage ist auch, ob man sich den Wert tausend mal pro sekunde neu berechnen lassen soll, oder ob 5 mal allenfalls genuegen wuerde. Oder auch nur ein mal pro sekunde.
Hallo, ich sehe weder bei unsigned long int hertz=123456789; noch bei hertz/1000000; die Notwendigkeit, eine wie auch immer geartete FP-Engine anzuwerfen. ist doch alles Ganzzahlarithmetik (wenigstens so, wie es da steht). im Ernst: einfach wie Benedikt bereits schrieb den Dezimaltrenner an der gewünschten Stelle einfügen, überflüssige Stellen einfach vorher abtrennen. ciao Marcus
Okay vielen lieben dank an euch alle :) Habt mir sehr die Augen geöffnet ... Habe mir jetzt soetwas hier geschrieben und es funktioniert prima ... Sieht nicht schön aus, aber tut hoffentlich effizient seinen Job! Für alle Anfänger die später noch davon profitieren möchten ... hier der Code :) Ich sage extra "Anfänger" weil die eingefleischten Hasen hier wahrscheinlich soetwas zwischen Bügeln und Kaffee Kochen erledigen können! PS: Khz routinen unvllständig ... noch void ShowFrequencyOnDisplay(){ // Wir muessen nicht immer neu-schreiben wenn keine Änderung erfolgt ist if(currentFrequencyDisplayRefresh==0) return; char* fr = calloc(35,sizeof(char)); char* original = calloc(35,sizeof(char)); ltoa(currentFrequency,original,10); if(currentFrequency>=100000000){ // Wir arbeiten im 3 Stelligen Mhz Bereich strncpy(fr,original,3); // Einerstelle strncpy(fr+3,",",1); // Komma strncpy(fr+4,original+3,5); strncpy(fr+9," Mhz",5); // SUFFIX } else if(currentFrequency>=10000000){ // Wir arbeiten im 2 Stelligen Mhz Bereich strncpy(fr,original,2); // Einerstelle strncpy(fr+2,",",1); // Komma strncpy(fr+3,original+2,5); strncpy(fr+8," Mhz",5); // SUFFIX } else if(currentFrequency>=1000000){ // Wir arbeiten im 1 Stelligen Mhz Bereich strncpy(fr,original,1); // Einerstelle strncpy(fr+1,",",1); // Komma strncpy(fr+2,original+1,5); strncpy(fr+7," Mhz",5); // SUFFIX } else if(currentFrequency>=1000){ // Wir arbeiten im Khz Bereich // TODO: ANNALOG WIE OBEN } else { // Wir haben nur Hertz, passiert aber ohnehin niemals :) LCDText("ERROR",2,2); } LCDText(fr,0,0); // Wir muessen nicht immer neu-schreiben wenn keine Änderung erfolgt ist currentFrequencyDisplayRefresh=0; }
Damit es Anfänger Nahvollziehen können nochmal die Erklärung: char* fr = calloc(35,sizeof(char)); char* original = calloc(35,sizeof(char)); Mit diesen zwei zeilen erstelle ich zwei 35 zeichen lange "Strings" die mit 0 gefüllt sind ... dies ist später nötig damit das LCD weiss wo schluss ist, denn 0 ist der terminate buchstabe. Jetzt haben wir ein long currentFrequency = 22344000; welches wir mittels ltoa(currentFrequency,original,10); in unser original einlesen, dabei werden bis zu 10 stellen mit Nullen (nicht Terminal \0) gefüllt... Nun ja und der Rest ist für jeden Mhz bereich gleich, nehmen wir z.B. die 3stelligen Mhz frequenzen: if(currentFrequency>=100000000){ // Wir arbeiten im 3 Stelligen Mhz Bereich strncpy(fr,original,3); // Einerstelle strncpy(fr+3,",",1); // Komma strncpy(fr+4,original+3,5); strncpy(fr+9," Mhz",5); // SUFFIX } Die Zeile strncpy(fr,original,3); (Äquivalent zu strncpy(fr+0,original,3); ) kopiert die ersten drei zeichen nach fr an die stelle 0, die erste stelle. Dann kommt das komma was mittels strncpy(fr+3,",",1); // Komma Nach der 3ten Stelle angefügt wird (Merke: fr+3 ist der zeiger auf stelle 4, da wir von 0 an zählen) Dann werden mit strncpy(fr+4,original+3,5); nach dem Komma was an stelle fr+4 also quasi an der 5ten stelle 5 Nachkommastellen angefügt ... Zum Glück haben wir oben gesagt dass wir den rest mit Nullen auffüllen wollen, sonst hätten wir ein Problem! nun haben wir genau 3+1(komma)+5 Stellen Belegt, also 9 stellen. Und mit strncpy(fr+9," Mhz",5); // SUFFIX kommt schlussendlich der Mhz Schriftzug nach der Stelle neun in unseren fr-String! Mehr brauchen wir nicht zu tun, da Stelle 11 dann eh der terminale Nullcharakter ist und das Display weiss, hier ist sense!
> char* fr = calloc(35,sizeof(char));
Wo sind die free() ?
holger, die habe ich natürlich vergessen :) schäm Ewig-Steigende Memory Footprints wollen wir natürlich auch in dem AVR nicht haben! Danke für den Hinweis!!!
> // Wir muessen ... > // Wir arbeiten ... > // Wir haben ... Wieso eigentlich immer WIR? ICH nicht mehr! Gute Nacht ;-)
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.