Forum: Compiler & IDEs Integer Zahl möglichst effizient auf Display ausgeben


von Chris S. (chris_05)


Lesenswert?

Hallo C-Gemeinde,

ich möchte einen Integer Wert möglichst effizient auf einem LCD 
ausgeben. Zum Thema "Zahl bearbeiten" habe ich auch schon viel gelesen, 
leider weiss ich nicht genau wie effizient die einzelnen Methoden 
(Division (Modulo), itoa etc.) sind.
Es handelt sich dabei z.B. um einen Wert von "25123456" (Temperatur) der 
auf dem Display "25.12" anzeigen soll. Die Display Ausgabe erfolgt ohne 
Bearbeitung der Zahlen mit sprintf wie folgt:

char data[10];
sprintf(data,"%i",value);
LCD_Print(data, ...);

Eine Möglichkeit wäre den Wert mittels itoa in einen String zu wandeln 
und dann das Komma an ensprechender Stelle einzufügen, dass würde dann 
etwa so aussehen:

char data[10];
itoa(value, data, 10);
char string[10];
string[0] = data[0];
string[1] = data[1];
string[2] = '.';
string[3] = data[2];
string[4] = data[3];
string[5] = '\0';
char str[10];
sprintf(str,"%s",string);
LCD_Print(data, ...);


Ich bin mir sicher Ihr kennt da noch elegantere Methoden. Ist es evtl. 
sinnvoller einen cast und Division (mit Modulo) durchzuführen? Mir geht 
es um eine möglichst effiziente Lösung, da die Schaltung unteranderem 
auch per Batterie versorgt wird.

Danke schon mal für eure Inputs!

von Peter D. (peda)


Lesenswert?

Chris S. schrieb:
> Mir geht
> es um eine möglichst effiziente Lösung, da die Schaltung unteranderem
> auch per Batterie versorgt wird.

Die Effizienz spielt für den schnarch langsamen Menschen überhaupt keine 
Rolle. Du merkst keinerlei Stromeinsparung.
Eher kann die benötigte Flash-Größe der Routine eine Rolle spielen.

von (prx) A. K. (prx)


Lesenswert?

Wenn printf sowieso dabei ist, dann ungefähr so:
1
ldiv_t qr = ldiv(value, 100);
2
sprintf(..., "%2ld.%02ld", qr.quot, qr.rem);

von Karl H. (kbuchegg)


Lesenswert?

Chris S. schrieb:


Solange du sowas machst ...

> char str[10];
> sprintf(str,"%s",string);
> LCD_Print(data, ...);

brauchst du dir um die Effizienz des Restes keine Sorgen machen. :-)

: Wiederhergestellt durch User
von Chris S. (chris_05)


Lesenswert?

@peda:
Mit Effizienz dachte ich eigendlich an die Anzahl Rechenschritte und 
auch Rechenoperationen (z.B. Division), die der Prozessor benötigt. Je 
aufwändiger die Berechnung desto mehr Leistung benötigt der uP.
Flash Speicher ist genügend vorhanden.

@prx:
Danke funktioniert soweit. Kannte die Funktion ldiv nicht.

von (prx) A. K. (prx)


Lesenswert?

Chris S. schrieb:
> Danke funktioniert soweit. Kannte die Funktion ldiv nicht.

Beim GCC muss man das genau genommen auch nicht. Der kriegt das nämlich 
spitz und dividiert bei
1
sprintf(..., "%2d.%02d", value/100, value%100);
nur einmal. Bei x86 ist das sogar effizienter als div().

von Yalu X. (yalu) (Moderator)


Lesenswert?

Wie schnell ändert sich die Temperatur? Sicher nicht sehr schnell.
Deswegen muss die Temperatur auf dem Display auch nicht im
Millisekundentakt aktualisiert werden, sondern es reicht vielleicht ein
Update alle 10 s aus. Die dazu benötigte mittlere elektrische Leistung
dürfte auch bei einem schlecht gewählten Algorithmus je nach Größe und
Typ der Batterie in der Größenordnung der Selbstentladung derselben
liegen.

von PittyJ (Gast)


Lesenswert?

Ich würde das in Assembler programmieren. Das geht am schnellsten, spart 
also am meisten Energie.
Alternativ geht auch ein Bimetallthermometer. Das kommt ganz ohne 
Energie aus.

von Rolf M. (rmagnus)


Lesenswert?

PittyJ schrieb:
> Alternativ geht auch ein Bimetallthermometer. Das kommt ganz ohne Energie
> aus.

Naja, Energie braucht es auch, aber die holt es sich aus der Umgebung, 
quasi per "energy harvesting" ;-)

von Peter D. (peda)


Lesenswert?

Chris S. schrieb:
> Je
> aufwändiger die Berechnung desto mehr Leistung benötigt der uP.

Wie schon gesagt, alle Berechnungen für den langsamen Menschen müssen so 
selten gemacht werden, da ist kein Leistungsunterschied meßbar, das sind 
vielleicht einige ppm.

Ein Mensch braucht aus Sicht der CPU enorm viel Zeit, um einen Wert 
abzulesen.

von Εrnst B. (ernst)


Lesenswert?

Chris S. schrieb:
1
 char data[10];
2
 itoa(value, data, 10);
3
 char string[10];
4
 string[0] = data[0];
5
 string[1] = data[1];
6
 string[2] = '.';
7
 string[3] = data[2];
8
 string[4] = data[3];
9
 string[5] = '\0';
10
 char str[10];
11
 sprintf(str,"%s",string);
12
 LCD_Print(data, ...);

Zum optimieren erstmal überlegen, warum das ganze so umständlich ist:
das ganze String-hin-und-herkopieren, das unnötige sprintf dazu usw, 
machst du nur, damit deine LCD_Print methode einen String als Parameter 
bekommt.
Was macht LCD_Print? Den String zeichenweise ans Display schicken. Das 
kannst du auch selber.
Also: statt LCD_Print direkt zeichenweise ausgeben. Spart den ganzen 
Hickhack.
1
 char data[10];
2
 itoa(value, data, 10);
3
 LCD_PrintChar(data[0]);
4
 LCD_PrintChar(data[1]);
5
 LCD_PrintChar(',');
6
 LCD_PrintChar(data[2]);
7
 LCD_PrintChar(data[3]);

(Bonus-Aufgabe: Temperaturen < 10° richtig anzeigen, "<space>5,67")

von M. N. (Gast)


Lesenswert?


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
Noch kein Account? Hier anmelden.