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.
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.
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
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.
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
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)
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;
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.
Vielen Dank an Rolf. Habe es jetzt so einigermaßen verstanden und es funktioniert super. Danke
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).
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.