Forum: Mikrocontroller und Digitale Elektronik Multiplikation mit Float


von Günni (Gast)


Lesenswert?

Hi,

ist eine Umwandlung von einer float-Variablen in eine char-Variable so 
aufwendig?

Folgende Zeilen belegen fast 30% des Gesamtspeicherplatzes:

        float Faktor = 0.8;
  char wert;

  if(Servo12 >= 240)
  Servo12 = 240;

  if(Servo12 >= 129)
  {
  wert =(Servo12 -129);
  wert =(wert * Faktor);
  wert =(129 + wert);
  }

  Servo12 = wert;

Was ist da faul?

von Karl H. (kbuchegg)


Lesenswert?

Günni wrote:
> Hi,
>
> ist eine Umwandlung von einer float-Variablen in eine char-Variable so
> aufwendig?

Ist es.

>
> Folgende Zeilen belegen fast 30% des Gesamtspeicherplatzes:

Das sagt noch gar nichts aus.
30% von 300 Byte sind 100 Byte -> nicht so arg viel
30% von 128 KByte, sind 40 KB  -> das ist heftig

>   float Faktor = 0.8;
>   char wert;
>
>   if(Servo12 >= 240)
>   Servo12 = 240;
>
>   if(Servo12 >= 129)
>   {
>   wert =(Servo12 -129);
>   wert =(wert * Faktor);

Du könntest dasselbe erreichen mit

    wert = wert * 8 / 10;

>   wert =(129 + wert);
>   }
>
>   Servo12 = wert;
>
> Was ist da faul?

Hast du den Optimizer nicht eingeschaltet?

Eine einzige Floating Point Operation führt dazu, dass
die komplette Floating Point Library mehr oder weniger
hinzugezogen wird. Und die braucht nun mal Platz.


von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Floating-Point-Arithmetik ist sehr viel aufwendiger als 
Integer-Arithmetik.

Du solltest, wenn möglich, daher versuchen, FP-Arithmetik zu vermeiden.

Dein Codebeispiel scheint, wenn ich es richtig interpretiere, einen 
8-Bit-Wert in einen anderen 8-Bit-Wert umzurechnen. Dazu braucht man 
schlimmstenfalls 256 Bytes Code, nämlich eine bereits vorberechnete 
Tabelle mit allen möglichen Werten.

von ARM-Fan (Gast)


Lesenswert?

Wär schön, wenn du mal deinen µC nennen würdest.
Aber bei einem Tiny z.B. mit wenig Flash könnte das schon sein.

Mal davon abgesehen läßt sich dein Problem mit der Skalierung
um Faktor 0.8 auch ganz leicht ohne Float-Arithmetik lösen.

Multiplizier deinen "wert" doch einfach mit 8 und teile dann durch 10.
Das geht dann ganzzahlig und deutlich resourcenschonender.

Mußt natürlich auf den Wertebereich deiner Variablen achten wenn
du multiplizierst.

von ARM-Fan (Gast)


Lesenswert?

3x 13:33 :-) und ich ein paar Millisekunden zu spät

von Günni (Gast)


Lesenswert?

Danke für die Antworten!

Das mit den mal 8 und geteilt durch 10 ist auf jeden Fall ne Ecke 
besser. Frisst kaum Resourcen.

Doch was ist denn der oben angesprochene Optimizer?

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Eine Option des C-Compilers.

von yalu (Gast)


Lesenswert?

Mit
1
wert = wert * 205 / 256U;
sparst du auch noch die Integerdivision, wobei trotz der scheinbaren
Ungenauigkeit des Ausdrucks die gleichen Ergebnisse geliefert werden
wie bei deiner oder Karl Heinzs Lösung. Wenn für die Variable wert
auch unsigned char geht (ich kenne den Wertebereich in deiner
Anwendung nicht), wird das Programm noch einmal 4 Bytes kürzer.

Noch ein Tip, falls du das nicht sowieso schon gemacht hast: Wenn du
irgendwo tatsäschlich Floatingpoint-Berechnungen brauchst, empfiehlt
es sich, die Mathebibliothek der avr-libc zu linken (-lm), auch wenn
keine trigonometrischen oder logarithmischen Funktionen benötigt
werden. Die avr-libc enthält für die Grundrechenarten handgemachte
Assemblerfunktionen anstelle der standardmäßig verwendeten
C-Funktionen der gcclib. Das spart in deinem Beispiel, wo drei der
Funktionen benötigt werden, ca. 1,5 KB Code.

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.