float in int umrechnen

Gast #53230
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.
Gast #53231
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.
Gast #53232
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
Gast #53233
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.
Gast #53235
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)
Gast #53236
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;
Gast #53237
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.
Gast #53239
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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren