mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik float in int umrechnen


Autor: Dag (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich hab eine Formel, welche eigentlich eine Rechnung in float vornimmt.
Soll es aber nicht, sondern in int.
z.B.
y=(x-261.12)/7.23
wobei x verschiedene werte annimmt(auch kleiner 261)

Wie muß ich jetzt die Formel umschreiben, damit er nicht mit
Kommawerten rechnet? Problem dabei ist die Bereichsbegrenzung vom
integer.

Für Vorschläge wäre ich dankbar.

Autor: Joerg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du skalierst sie.

Du schreibst nicht, für welchen Prozessor/Compiler, ich gehe mal davon
aus, daß Du einen signed int von 16 Bits hast, der kann also Werte von
-32768 bis 32767 abbilden.  Nun brauchst Du die minimalen und
maximalen Werte, die x annehmen kann, damit bekommst Du den
größtmöglichen Skalierungsfaktor.  Mal angenommen, x kann maximal 300
sein, dann wäre der Faktor 32767 / 300 =~ 100.  (Schade, 128 wäre
einfacher, weil man dann nur 7 bits nach links schieben muß.)

Es dürfte genauer werden, wenn Du ausklammerst und den konstanten
Quotienten auf der rechten Seite vorab skalierst.

Autor: Dag (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke,
hab es aber ehrlich gesagt nicht ganz verstanden.
Ich arbeite mit dem AT90S4433.
Also mir stehen 16 Bit Register zur Verfügung.
Die x-Werte kommen aus dem internem AD Wandler und können
Werte von 0 bis 1024 annehmen.
Der y-Wert soll ein integer sein.

Danke

Autor: Rolf F. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich würde so skalieren:


#include <limits.h>

y = (int) ( (x-261.12)/7.23  SKAL  ((float) INT_MAX) );


SKAL muss so gewählt werden, dass der Wert von (x-261.12)/7.23 * SKAL
betragsmäßig maximal 1,0 ist.

Autor: Dag (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tut mir leid,
aber das funktioniert nicht.
Habe SKAL einen Wert von 1/110 zugeordnet.
Wofür ist den eigentlich die limits.h da?
Was soll den in dieser Gleichung passieren?

Danke

Autor: Dag (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schuldigung,
geht doch, hatte den falschen SKAL-Faktor.
Da von 0 bis 1024 -> SKAL=32767*1024=32
y=(int) ((x-261.12)/7.23*32)*((float) INT_MAX) );

So geht es jetzt bei mir.
Würde mich trotzdem freuen, wenn mir einer erklärt, was nun genau
in der Gleichung passiert.
Mich interessiert besonders das (int) und (float)

Autor: Rolf F. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also (int) wandelt (engl. castet) in den Datentyp int um usw..

Und SKAL muss der Kehrwert des betragsmäßigen Maximalwerts (von
(x-261.12)/7.23 ) sein; dann liegt y im Bereich -INT_MAX ... INT_MAX,
wobei -INT_MAX oder -INT_MAX-1 gleich INT_MIN sein sollte (genau stehts
in limits.h).
Durch diese Skalierung ist der Rundungsfehler minimal.
Wenn man es genau machen will, dann berücksichtigt man, dass beim cast
abgeschnitten (abgerundet) wird und rundet entspechend richtig:


#include <limits.h>

f_tmp = ( (x-261.12)/7.23  SKAL  ((float) INT_MAX) );

f_tmp += (dtmp > -0.5) ? 0.5 : -0.5;

y = (int) f_tmp;

Autor: Rolf F. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nachtrag: Vor der letzten Zeile sollte wegen eventuellen Rundungsfehlern
noch

if (f_tmp > ((float) INT_MAX)
  f_tmp = INT_MAX;
if (f_tmp < ((float) -INT_MAX)
  f_tmp = -INT_MAX;


eingesetzt werden.

Autor: Dag (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank an Rolf.
Habe es jetzt so einigermaßen verstanden und es funktioniert super.

Danke

Autor: Rolf F. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gut.
Übrigens muss man im Allgemeinen noch auf NAN und manchmal auch auf
+inf und -inf überprüfen. isnan() und isinf() sind deshalb auch beim
mspgcc dabei (notfalls kann man das bischen Code nach IEEE 754 auch
selbst schreiben).

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.