Hi Leute!
Ist es möglich eine Art von itoa mittels Shiftoperationen zu machen?
Ich merke schon deutlich einen Speicherplatzunterschied wenn ich z.B.
anstatt durch 32 teilen einen Rechtsshift um 5 mache. Das macht bei mir
hier gerade einen Unterschied von 268 Byte aus (mein Controller hat 2k).
Ich habe hier meine eigene Funktion
Optimierung ausgeschaltet? Der Compiler benutzt automatisch Shifts, wenn
Zweierpotenzen im Spiel sind.
Wenn du Platz sparen willst, lass es lieber für solch triviale Sachen
Structs zu benutzen.
Und nein, Shifts im Binärsystem bringen dir nichts im Dezimalsystem.
Divisionen sind teuer. Aber das wirst Du auch schon festgestellt haben.
In Assembler ließe sich sowas noch mehr optimieren, aber hast du mal
etwas im Stil von dem da probiert:
1
voiditoa(unsignedintinput,char*digits)
2
//digits muss ein Array sein das hinreichend groß ist.
3
{
4
unsignedcharucplace=0;
5
unsignedintuidiv;
6
7
while(ucplace<MAXDIGITS)
8
{
9
switch(ucplace)
10
{
11
case0:
12
{
13
uidiv=10000;
14
break;
15
}
16
case1:
17
{
18
uidiv=1000;
19
break;
20
}
21
...//Die restlichen Zuweisungen, bis runter zu case 4: uidiv=1;
22
}
23
24
while(input>=uidiv)
25
{
26
input-=uidiv;
27
digits[ucplace]++;
28
}
29
}
30
return;
31
}
Hab ich jetzt nur mal runtergeschrieben und nicht ausprobiert, aber die
Idee ist, so lang die höchste 10er Potenz abzuziehen (und die Anzahl zu
zählen) bis der Rest kleiner ist, dann die nächstniedrigere 10er Potenz
zählen usw.
Sollt klappen, schneller sein und weniger Platz fressen. In ASM könnte
man hier noch einiges mehr optimieren... ich guck mal ob ich Zeit finde,
brauchen kann man sowas bekanntlich immer mal.
Harglbar schrieb:> Optimierung ausgeschaltet? Der Compiler benutzt automatisch Shifts, wenn> Zweierpotenzen im Spiel sind.
Hm. Von welcher Firma ist denn das Produkt "Der Compiler"?
Das sollten man schon wissen, bevor man solche Aussagen trifft.
Eine Optimierung, soweit vorhanden, sollte man aber schon einschalten.
Oliver
Sven schrieb:> Nachtrag: Nimmt eine Multiplikation mit -1 auch verhältnismäßig mehr> Speicher weg als eine Addition? Geht das auch anders?
ZAHL = ~(ZAHL)+1
bzw
ZAHL = ~(ZAHL-1)
Sven schrieb:> source_number *= -1;Sven schrieb:> Nachtrag: Nimmt eine Multiplikation mit -1 auch verhältnismäßig mehr> Speicher weg als eine Addition? Geht das auch anders?bitshift schrieb:> ZAHL = ~(ZAHL-1)
Soll ich jetzt lachen oder weinen?
Harglbar schrieb:> Wenn du Platz sparen willst, lass es lieber für solch triviale Sachen> Structs zu benutzen.
Verbrauchen structs mehr Platz als einzelne Variablen?
Sven schrieb:> (mein Controller hat 2k)
So, 2k WAS? Dein Controller hat nur 2 K Byte Befehlsspeicher oder 2 K
Befehle? Ist also vermutlich ein kleiner 8 Bitter.
Und da willst du solche Hilfsroutinen wie das Ausgabekonvertieren von
Integers in C schreiben, ohne dich intensiv um die in den mitgelieferten
Bibliotheken vorhandenen Funktionen zu kümmern. Ah ja.
Such einfach mal nach der Funktion ldiv. Die müßte es bei IAR auch für
die kleineren uC geben - und wenn du sie gefunden hast, dann schreib
deine Ziffernroutine neu.
Ich geb dir hier mal einen Ausschnitt aus ner Konvertierung (die
Formatierungen hab ich weggelassen):
long LtoStr (long aValue, int digits, char* Buffer, int BufLen)
...
i = BufLen - 1;
Buffer[i--] = 0; /* Endemarker setzen */
if (aValue<0)
{ L = -aValue;
v = 1;
}
else { L = aValue;
v = 0;
}
if (!L) Buffer[i--] = '0';
while (i)
{ if (!L) goto _lready;
T = ldiv(L,10);
L = T.quot;
Buffer[i--] = '0'+T.rem;
}
/* i = 0 heisst: der Buffer ist voll! */
i = 0; j = BufLen - 2;
Buffer[i++] = '>';
while (i<j) Buffer[i++] = '9';
return aValue;
_lready:
...
Aber bei einem uC mit nur 2 K Programmspeicher würde ich zumindest
solche Routinen in Assembler schreiben und nicht ldiv, sondern die von
Peter Dannegger skizzierte Subtraktionsmethode benutzen. Die braucht
lediglich Subtraktionen und ein paar Zehnerpotenzen als Konstanten.
W.S.
Eine eigene Frage?
Dieser Thread ist über 14 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.