Forum: Mikrocontroller und Digitale Elektronik Berechnung ohne Gleitkomma


von Martin S. (drunkenmunky)


Lesenswert?

Hallo,
ich will ein variablen Wert nach folgender Gleichung berechnen ohne die 
Gleitkommabibliothek zu verwenden

PR2 = (5e5 / freq ) - 1

Ist das irgendwie (näherungsweise) möglich? Mir fehlt da irgendwie die 
Idee.

von Karl H. (kbuchegg)


Lesenswert?

5 mal 10 hoch 5, ist 50000
geht doch noch wunderbar in einen unsigned int hinein.

von Lehrmann M. (ubimbo)


Lesenswert?

http://www.mikrocontroller.net/articles/Festkommaarithmetik

Karl heinz Buchegger schrieb:
> 5 mal 10 hoch 5, ist 50000
> geht doch noch wunderbar in einen unsigned int hinein.

Sorry Meister ab ich glaub da fehlt eine 0 wenn ich das richtig sehe.

von U.R. Schmitt (Gast)


Lesenswert?

Und wenn freq sagen wir mal nicht größer als 2000 wird, wirds auch 
erträglich genau.

von Karl H. (kbuchegg)


Lesenswert?

Lehrmann Michael schrieb:
> http://www.mikrocontroller.net/articles/Festkommaarithmetik
>
> Karl heinz Buchegger schrieb:
>> 5 mal 10 hoch 5, ist 50000
>> geht doch noch wunderbar in einen unsigned int hinein.
>
> Sorry Meister ab ich glaub da fehlt eine 0 wenn ich das richtig sehe.

Ich hätte doch auf meine Finger vertrauen sollen beim zählen :-)
Hast natürlich recht.

* auf long ausweichen
* Oder freq vorher durch 10 dividieren

Hängt jetzt davon ab, wieviel Fehler man sich erlauben kann/darf und 
welche Werte freq so annehmen wird.

von U.R. Schmitt (Gast)


Lesenswert?

Lehrmann Michael schrieb:
> Sorry Meister ab ich glaub da fehlt eine 0 wenn ich das richtig sehe.

Nene, Karl Heinz hat freq im Kopf schon durch 10 geteilt :-)

Wäre sinnvoll wenn der TO uns etwas über den Wertebereich von freq und 
den max. zulässigen Rechenfehler erzählen könnte.

von Martin S. (drunkenmunky)


Lesenswert?

Hi, danke für die Antworten.

ich will eine Funktion machen, der eine Frequenz in Hz (freq) übergeben 
wird und daraus die nötigen Registerwerte für die PWM berechnet. Das PWM 
Signal ist nur für einen Summer, also muss nicht sonderlich genau sein.

Zuerst hatte ich es ohne (long) und habe mich gewundert, dass er dafür 
die Gleitkommabib braucht.

Jetzt habe ich es so:
PR2 =  (uint8_t)(( (long)5e5 / freq ) - 1 );

Geht es noch platzsparender?

von Martin S. (drunkenmunky)


Lesenswert?

scheinbar nicht...

von Karl H. (kbuchegg)


Lesenswert?

Martin S. schrieb:
> Hi, danke für die Antworten.
>
> ich will eine Funktion machen, der eine Frequenz in Hz (freq) übergeben
> wird und daraus die nötigen Registerwerte für die PWM berechnet. Das PWM
> Signal ist nur für einen Summer, also muss nicht sonderlich genau sein.
>
> Zuerst hatte ich es ohne (long) und habe mich gewundert, dass er dafür
> die Gleitkommabib braucht.
>
> Jetzt habe ich es so:
> PR2 =  (uint8_t)(( (long)5e5 / freq ) - 1 );
>
> Geht es noch platzsparender?

Wenn du alle Zahlen durch 16 dividierst, wird es kleiner und schneller, 
vorausgesetzt freq ist unsigned int. Wenn nicht, castest du es zurecht.

  uint16_t tmp = ((uint16_t)freq) / 16;
  PR2 = 31250U / tmp - 1;

Wenns sowieso nicht so genau sein muss.

von U.R. Schmitt (Gast)


Lesenswert?

Und bedenke, daß dein Wert freq nicht kleiner sein darf als 500000/256 
also etwa 2000 da sonst das uint8_t Ergebnis überläuft.
Bedenke ebenfalls daß bei hohen Frequenzen die Auflösung ziemlich klein 
ist.
Für 450000 kriegst Du das selbe Ergebnis wie für 260000, nämlich 1.

von eProfi (Gast)


Lesenswert?

Karl-Heinz, warum kürzt Du mit 16, wenn 8 auch reicht?

PR2 = 62500U / (((uint16_t)freq/8) - 1);//mit 8 gekürzt für 
16bit-Division

Vermutung: die Float-Lib hat er geladen, da der das 5e5 gesehen hat, 
hättest Du 500000L geschrieben, würde er die long-Div verwenden.

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.