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

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.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.