Hallo
Ist nicht so wichtig doch ich dachte mir
fragste mal.
unsigned char GetPlot(char Kurve){
int dummy;
dummy = (round( pow(2, Kurve)));
return ( dummy >> 1 );
}
funktioniert wunderbar nur kann man die Funktion, vereinfachen?
Das dumme dabei 2hoch8 ergibt 256 also 1 byte + 1
deswegen brauche ich den int dummy.
Vielleicht lerne ich mal wieder was
Danke im voraus
Da gibt es doch nur einen winzigen Wertebereich für die Eingabe "Kurve".
IMO wäre dann ein switch(Kurve){} effizienter, allerdings auch viel mehr
Zeilen in C.
Wenn "Kurve" immer positiv ist, müsste dann nicht
unsigned char Kurve
als Übergabeformat eingetragen sein? Dann würde auch Dummy zu einem
uint16 und somit könnte der Compiler das wahrscheinlich vereinfachen.
Karl Heinz wird das alles erklären. :-)
Aber mal so hingefragt: Was ist:
2^1 (pow(2,1))
2^2 (pow(2,2))
2^3 (pow(2,3))
Hint: Hier liegt der Sonderfall der Basis 2 und von integer-Exponenten
vor.
Du rechnest also Zwei hoch Kurve, um dann das Ergebins durch zwei zu
teilen.
Warum dann nicht gleich Zwei hoch (Kurve-1) ?
EDIT:
Da Kurve immmer eine Ganzzahl ist, kommen auch nur Ganzzahlen als
Ergebnis von pow raus. Somit sollte doch das round unnötig sein...?
>> Du rechnest also Zwei hoch Kurve, um dann das Ergebins durch zwei zu> teilen.>> Warum dann nicht gleich Zwei hoch (Kurve-1) ?>> EDIT:> Da Kurve immmer eine Ganzzahl ist, kommen auch nur Ganzzahlen als> Ergebnis von pow raus. Somit sollte doch das round unnötig sein...?
Und das pow ist auch gleich unnötig. Siehe meine Frage oben.
Wozu erst in double rechnen, wenn sowohl die Argumente als auch das
Resultat integer sind?
Aber wie gesagt: Das wird Karl Heinz alles erklären, und:
"Vielleicht lernst Du mal wieder was".
So ein paar Grundlagen müssen ja auch mal gelernt werden.
Was noch bleibt, sind implzite Umwandlungen und Promotion.
Klaus schrieb:> Aber wie gesagt: Das wird Karl Heinz alles erklären, und:
Was soll ich da gross erklären?
Offenbar kann 'Kurve' sowíeso nur Werte zwischen 0 und 8 annehmen.
Ansonsten würde der Return Datentyp keinen Sinn machen. Also wozu lange
rumrechnen? Bei 9 verschiedenen Ergebnissen macht man ein Array, in dem
man die Werte im voraus ausrechnet und einen davon zurückliefert und gut
ists.
Getreu dem alten Motto: Space for Time
Karl H. schrieb:> Klaus schrieb:>>> Aber wie gesagt: Das wird Karl Heinz alles erklären, und:>> Was soll ich da gross erklären?
Nichts. Entschuldigung.
Danke für die vielen Antworten
ja round ist unnötig kommt noch von der funktion wo ich sinus noch drin
hatte
sorry
nein kein array ich wollte nur wissen ob
ich den Buffer dummy int 16 bit weglassen könnte.
Als Hintergrund
Ich gebe auf ein LED Display mit 8 x 16 Led's
Das mache ich mit spi und zwei PIC16F887
Muster aus und da dachte fängst Du mal mit einer Sinuskurve an. .-)
Martin M. schrieb:> nein kein array ich wollte nur wissen ob> ich den Buffer dummy int 16 bit weglassen könnte.
Mach dir deswegen keinen Kopf. Compiler sind gut darin, Variablen
rauszuwerfen, die keiner braucht. Kümmere du dich um die Logik und
überlass den Rest dem Compiler.
Wenn du die Funktion vereinfachen willst, dann sieh zu, dass du das pow
los wirst und auch das round. Dort hast du Potential. Aber über
funktionslokale Variablen brauchst du dir keinen Kopf machen, ausser es
sind viele und ausser es sind Arrays. Aber aus deiner Funktion intern
ein
1
unsignedcharGetPlot(charKurve){
2
return(int)((round(pow(2,Kurve))))>>1;
3
}
zu machen, ist für eine Compiler eine leichte Übung. Nicht jede
Variable, die in deiner Funktion vorkommt, führt auch dazu, dass
irgendwo Speicher dafür reserviert wird. Compiler können das problemlos,
dass sie über die Verwendung der Register Buch führen und welcher Wert
wann in welchem Register liegt. Wenn es reicht, diesen Wert von dort
wieder weiter zu verwenden, gibt es keinen Grund, warum der Wert jemals
ins SRAM gespeichert werden soll. Wenn es nichts zu speichern gibt,
braucht man auch keine Speicherreservierung dafür.
Aber all das soll dich nicht kümmern. Du kümmerst dich um die Logik und
schreibst sie so, wie es für dich am verständlichsten ist. Wenn es mit
Hilfsvariablen für dich am verständlichsten ist, dann schreibst du das
eben mit Hilfsvariablen und der Compiler formt das wieder so um und
stutzt es zurecht, dass die Hilfsvariable rausfliegt. Die dazu
notwendige Technik beherrschen die Compilerbauer seit Jahrzehnten.
Karl H. schrieb:> Kümmere du dich um die Logik und überlass den Rest dem Compiler.
Genau so sieht's aus.
Wenn man nicht gerade einen total ungeeigneten Algorithmus verwendet,
dann ist nahezu jeder Code gut solange er:
-korrekte Ergebnisse liefert (durch Tests nachgewiesen)
-lesbar und verständlich ist (auch nach Jahren noch)
Alles andere ist Zeit vergeudet an der falschen Stelle.
Übrigens: Für nicht genutzte Rechenzeit oder nicht genutzten Speicher
gibt es kein Geld zurück ;-)
Karl H. schrieb:> Klaus schrieb:>>> Aber wie gesagt: Das wird Karl Heinz alles erklären, und:>> Was soll ich da gross erklären?>> Offenbar kann 'Kurve' sowíeso nur Werte zwischen 0 und 8 annehmen.> Ansonsten würde der Return Datentyp keinen Sinn machen. Also wozu lange> rumrechnen? Bei 9 verschiedenen Ergebnissen macht man ein Array, in dem> man die Werte im voraus ausrechnet und einen davon zurückliefert und gut> ists.> Getreu dem alten Motto: Space for Time
Genau das hab ich mich auch gefragt als ich den Post gelesen habe.
Ich würde es so schreiben:
1
unsignedcharGetPlot(unsignedcharKurve){
2
intdummy[9]={1,2,4,8,16,32,64,128,256};
3
if(((unsignedint)Kurve-1)>8)return-1;//parameter ausserhalb des zulaessigen Wertebereichs
4
return(unsignedchar)dummy[(unsignedint)Kurve-1];
5
}
In C bin ich nicht sonderlich gut aber muss/sollte der Rückgabewert
nicht auch unsigned char sein wenn die Funktion unsigned char ist?
@Martin
Und da ich es ungewöhnlich finde, dass du da einen char als
Funktionsparameter hast: Du willst wirklich den Intergerwert des
übergebenen Chars benutzen, es ist nicht so dass da als Zeichen eine
z.B. 6 (hat den Integerwert 54) kommt?
Shift schrieb:> Im oben genannten Fall ist ein Shift-Left viel schneller und braucht> weniger Code als ein Array.
schnell ist abhängig von der CPU. Bei den Atmels kann das Array durchaus
schneller sein.
Peter II schrieb:> Shift schrieb:>> Im oben genannten Fall ist ein Shift-Left viel schneller und braucht>> weniger Code als ein Array.>> schnell ist abhängig von der CPU. Bei den Atmels kann das Array durchaus> schneller sein.
Zumindest bei AVR. Da dieser nicht shiften kann, muss er einen Shift
über eine variable Anzahl von Bits über wiederhote Additionen in einer
Schleife nachbilden.
Michael K. schrieb:> unsigned char GetPlot(unsigned char Kurve) {>> if ( ((unsigned int)Kurve-1) > 8 ) return -1; //parameter ausserhalb> des zulaessigen Wertebereichs
Wenn man negative Werte zurückliefern will, sollte der Return-Typ aber
auch vorzeichenbehaftet sein.
Shift schrieb:> Warum überhaupt ein Array ?>> Im oben genannten Fall ist ein Shift-Left viel schneller und braucht> weniger Code als ein Array.>> Also:>
1
>unsignedcharGetPlot(unsignedcharKurve){
2
>//parameter ausserhalb des zulaessigen Wertebereichs
3
>if(Kurve>8||Kurve==0){
4
>return-1;
5
>}
6
>return1<<(Kurve-1);
7
>}
8
>
Kommt auf den Prozessor an.
Auf einem AVR muss dein 1<<(Kurve-1) zu dem hier umgeformt werden:
1
....
2
unsignedcharmask=0x01;
3
{
4
unsignedchartmp;
5
for(tmp=Kurve;tmp>0;tmp--)
6
mask<<=1;
7
}
8
returnmask;
immer noch überzeugt, dass das in allen Fällen schneller ist als ein
simpler Array Zugriff, d.h. eine Dereferenzierung eines Basepointer +
Offset? Vor allen Dingen dann, wenn man das Array static macht, so dass
es nicht jedesmal neu initialisiert werden muss.
Auf einem AVR willst du keine Shifts mit variabler Anzahl an Bits haben,
wenn es auch andere Möglichkeiten gibt.
Returnwert -1 und unsigned char geht doch nicht zusammen, oder?
Müsste int sein, damit man das -1 auch rausbekommt.
Ah, ja, Peter hat's schon geschrieben.
Ich sagte ja, so doll bin ich in C nicht. Und ob jetzt Shift oder Array
schneller ist auf dem AVR weiß/wusste ich auch nicht. Und klar, das
return -1 ist für unsigned auch wenig schön. In der Regel schreib ich
ein Programm/Funktion erst mal so runter und kümmere mich dann um die
Warnings die mir der Compiler nennt. Ich hab ETechnik studiert und unser
Informatik-Prof hat uns beigebracht: Es gibt keinen Grund Warnings zu
ignorieren! Ich hab aber obige Funktion nicht dem Compiler zum
verarbeiten gegeben gehabt, das war mehr frei Schnautze runter
geschrieben ;)
Conny G. schrieb:> Returnwert -1 und unsigned char geht doch nicht zusammen, oder?> Müsste int sein, damit man das -1 auch rausbekommt.>> Ah, ja, Peter hat's schon geschrieben.
Richtig, da käme 255 raus und das ist auch das Problem, dass ich mit dem
Funktionswert sehe: wie kann die Funktion 256 zurückliefern wenn sie
unsigned char ist? Das geht nur bis 255 ;)
Conny G. schrieb:> Returnwert -1 und unsigned char geht doch nicht zusammen, oder?> Müsste int sein, damit man das -1 auch rausbekommt.
Die erste Frage sollte allerdings lauten:
Kann es überhaupt passieren, dass hier der Funktion ein ungültiges
Argument übergeben wird oder ist das durch die Vorgeschichte schon
ausgeschlossen und es reicht in diesem Fall (wenn überhaupt) zb immer
das Ergebnis für 0 zu liefern.
Michael K. schrieb:> unser> Informatik-Prof hat uns beigebracht: Es gibt keinen Grund Warnings zu> ignorieren!
Das ist auch richtig so.
In der professionellen Programmierung wird das so gehandhabt, dass der
Compiler auf dem höchsten (oder zweithöchsten) Warninglevel einen
Programmtext ohne jegliche Warnung compilieren muss. Alles andere wird
als fehlerhaft gewertet und muss behoben werden. Egal ob echter Fehler
oder Warnung. Nur allzuoft sind Warnungen tatsächliche Probleme, die
nicht ignoriert werden können.
Peter II schrieb:> sinnvollerweise sollte das Array aber noch const static sein. Und die> Anmerkung mit dem return -1 sollte man auch berücksichtigen.
Warum static? Sorgt das nicht dafür, dass ein Teil des RAMs für das
Array reserviert bleibt auch wenn die Funktion grade gar nicht benutzt
wird?
Und return 0 würde ich auf keinen Fall machen, ein retrun 0 lese ich
immer als "kein Fehler", hier wäre aber ein Fehler aufgetreten. Ob ich
mich nach 5 Monaten noch dann dabei erinnern würde, wenn ich mir den
Code noch mal anschaue, dass das return 0 hier dann bedeutet, dass ein
Fehler auftrat? Ne, da auf jeden Fall was anderes, am liebsten halt ein
return -1 und da IMO die funktion eh einen anderen Datentyp als unsigned
char braucht würde ich hier gleich was signed benutzen.
Michael K. schrieb:> Peter II schrieb:>> sinnvollerweise sollte das Array aber noch const static sein. Und die>> Anmerkung mit dem return -1 sollte man auch berücksichtigen.>> Warum static? Sorgt das nicht dafür, dass ein Teil des RAMs für das> Array reserviert bleibt auch wenn die Funktion grade gar nicht benutzt> wird?
Tut es.
Aber erstens sind es nur 8 Byte und zweitens fällt dann die ständige
Initialisierung des Arrays beim AUfruf der Funktion weg.
Wer will, kann das Array ja auch noch ins Flash legen. Das ist dann der
speichertechnisch günstigste Fall.
> Und return 0 würde ich auf keinen Fall machen, ein retrun 0 lese ich> immer als "kein Fehler", hier wäre aber ein Fehler aufgetreten.
Kommt drauf an.
Das ist ganz klar eine Berechnungsfunktion, bei der ein Wert ungleich 0
ein sinnvolles Resultat ist, während 0 nicht vorkommen kann.
Michael K. schrieb:> Warum static? Sorgt das nicht dafür, dass ein Teil des RAMs für das> Array reserviert bleibt auch wenn die Funktion grade gar nicht benutzt> wird?
ja und das ist auch gut so, dann muss es nicht jedes mal neu geladen
werden.
Peter II schrieb:> Michael K. schrieb:>> Warum static? Sorgt das nicht dafür, dass ein Teil des RAMs für das>> Array reserviert bleibt auch wenn die Funktion grade gar nicht benutzt>> wird?>> ja und das ist auch gut so, dann muss es nicht jedes mal neu geladen> werden.
Das ist natürlich ein Argument und wie Karl Heinz schrieb: am Besten im
Flash liegen lassen ;)
Michael K. schrieb:> Das ist natürlich ein Argument und wie Karl Heinz schrieb: am Besten im> Flash liegen lassen ;)
Da muss es ja zwangsweise sowieso schon liegen, von daher drängt sich
das geradezu auf.
Rolf M. schrieb:> Da muss es ja zwangsweise sowieso schon liegen, von daher drängt sich> das geradezu auf.
die wie nicht wissen, auf welcher Hardware es laufen soll. Muss der
Hinweis const dem Compiler reichen und damit landet es schon im Flash -
außer den atmels.