Forum: Compiler & IDEs minifloat / float 16 oder fixed point Variablen für 8 Bit AVR


von delicious_cake (Gast)


Lesenswert?

Hallo,

ich wollte mich mal erkundigen wie ich auf einem 8-bit AVR eine 16 bit 
float variable statt einer 32 bit float variable umsetzen kann?

oder eventuell eine fixed point variable mit 2 nachkommastellen? da 
würden schon 8 bit reichen.


ich freu mich über jede hilfreiche antwort

von Karl H. (kbuchegg)


Lesenswert?

delicious_cake schrieb:
> Hallo,
>
> ich wollte mich mal erkundigen wie ich auf einem 8-bit AVR eine 16 bit
> float variable statt einer 32 bit float variable umsetzen kann?

Gar nicht.
16 Bit float macht im Allgemeinen wenig Sinn, weil die Zahlenauflösung 
hinten und vorne nicht ausreicht um damit irgendetwas sinnvolles 
anfangen zu können.

> oder eventuell eine fixed point variable mit 2 nachkommastellen? da
> würden schon 8 bit reichen.

Das ist der Weg, den du gehen musst.

Einfach alle Zahlen mal 100 nehmen und bei der Ausgabe vor der 
Hunderterstelle wieder ein Komma an der richtigen Stelle einschmuggeln.

Anstatt in Euro  ( 2.45 = 2 Euro 40 Cent) rechnest du programmintern 
einfach alles in Cent (245 Cent) und du hast 'Euros mittels 
Fixpointformat mit 2 Nachkommastellen' berechnet.

Addition + Subtraktion
   Hier ist kein Aufwand nötig. Einfach die Operation ausführen.
   Ob man 2.45 + 3.78  gleich 6.23
     oder 245 + 378    gleich 673
   ist egal, es kommt das richtige raus.

Multiplikation + Division
   Hier muss nach bzw. vor der Operation wieder ein Normierungsschritt
   gemacht werden.

   Annahme: Fixpointformat mit 2 Nachkommastellen

    d.h. die Zahl 1.00  wird als 100 dargestellt

    1.00 * 1.00  muss wieder 1.00 ergeben
    100 * 100 ergibt aber 10000.
    Dieses Ergebnis normieren, indem man durch die 100 dividiert
    ergibt dann wieder 100 (also 1.00 in weltlicher Darstellung) und
    damit das richtige Ergebnis.
    Ist auch logisch, denn im Grunde hat man ja gerechnet
1
    ( 1.00 * 100 )    *    (1.0 * 100)  =     ( 1.0 * 1.0 * 100 * 100 )
2
     die erste Zahl        die zweite Zahl         Ergebnis
    und jetzt sieht man, dass man im Ergebnis einmal zuviel mit 100
    multipliziert hat, die man wieder entfernen muss.

von delicious_cake (Gast)


Lesenswert?

eigentlich geht es nur darum speicher zu sparen. ich habe nur werte im 
bereich von 1,.. bis 2048,00. Da reicht eine minifloat vollkommen aus. 
die gibts übrigens auch nach norm, nur leider nicht bei der gcc-libc.

von Klaus W. (mfgkw)


Lesenswert?

delicious_cake schrieb:
> die gibts übrigens auch nach norm

nach welcher Norm?

von Bernhart (Gast)


Lesenswert?

mittlerweile habe ich den artikel über datentypsnormungen vor 2 tagen 
gelesen, deshalb bin ich mir jetzt nicht mehr ganz sicher wo das drin 
steht. Ich finde den Artikel leider auch nicht mehr.

Jedenfalls wird auf Wikipedia über 16 bit floats geschrieben. Was ich da 
gelesen habe war anscheinend irgendwas falsches. Lt. Wiki werden 
Minifloats  möglicherweiße in einer Zukünftigen Norm enthalten sein. 
Minifloats werden jetzt nur in Spezialanwendungen verwendet und sind 
meistens nach richtlinien von IEEE 754 definiert.

http://de.wikipedia.org/wiki/IEEE_754
http://de.wikipedia.org/wiki/Minifloat

von Klaus W. (mfgkw)


Lesenswert?

ok, also nur für Schulungen - damit man nicht soviel an der Tafel
malen muß und die Schüler etwas mehr Übersicht behalten.
Sinnvoll rechnen kann man damit in aller Regel nicht.
4 Byte lange float nach IEEE 754 haben ja bereits nur etwa 6
signifikante Stellen (ins Dezimale umgerechnet).
Weniger macht kaum Sinn.

Um noch zu sparen, kann man sinnvollerweise nur Ganz- oder genau
angepasste Festkommazahlen nehmen.

von Klaus W. (mfgkw)


Lesenswert?

PS: Es gibt hier im Forum bereits etliche Artikel zu Festkommazahlen.
Und eine Suchfunktion :-)

von Rolf Magnus (Gast)


Lesenswert?

16-Bit-Gleitkommazahlen werden durchaus verwendet, und zwar in 
3D-Beschleunigern. Diese unterstützen in der Regel einen solchen Typ 
direkt in der Hardware. Der heißt dort meistens "half" oder "hfloat". 
Genutzt wird er vor allem für die Berechnung der Pixel bei sogenanntem 
HDR-Rendering. Früher wurde für die drei Grundfarben immer je ein 
8-Bit-Integer verwendet. Bei HDR-Rendering verwendet man 
Gleitkomma-Zahlen, um einen (nach unten und oben) großen Zahlenbereich 
abdecken zu können, beschränkt es aber auf 16 Bit, um nicht so viel 
Speicherbandbreite zu brauchen.

von eklige Tunke (Gast)


Lesenswert?

Klaus Wachtler schrieb:
> Um noch zu sparen, kann man sinnvollerweise nur Ganz- oder genau
> angepasste Festkommazahlen nehmen.
Gibt es da Festkommazahlen die halbwegs allgemein genutzt werden oder 
verbreitet sind? Ich habe mal gehört dass die dsPICs da was in einer Lib 
haben, gibt es da auch noch was anderes?

von Klaus W. (mfgkw)


Lesenswert?

"allgemein" hier im Forum wird immer erzählt, wie man es manuell macht.
Also Zeile für Zeile altgermanisch im Quelltext.

"allgemein" bei mir nehme ich meine eigene Lösung, die ist allerdings
in C++ und deshalb hier nicht besonders mehrheitsfähig.
Zu erreichen auch über die Suchfunktion hier ("Festkommazahlen in Würde"
oder so ähnlich).

Noch allgemeiner wüsste ich nichts.
Wenn doch, ist es bestimmt über die Suche zu finden...

von delicious_cake (Gast)


Lesenswert?

@ Klaus Wachtler:
Danke das sieht nach einer sehr guten Lösung aus.

Andererseits gibt es ja die Möglichkeit den float Datentyp zu 
konfigurieren (float.h). Wie gebraeuchlich ist das und was kann ich 
damit alles erreichen? Kann man mit ein paar Anpassungen evtl. die 
Rechenzeit verkürzen? (z.B. kleiner Genauigkeit hinter dem Komma)

von eklige Tunke (Gast)


Lesenswert?

Klaus Wachtler schrieb:
> "allgemein" hier im Forum wird immer erzählt, wie man es manuell macht.
> Also Zeile für Zeile altgermanisch im Quelltext.
Ja, per Hand kann ich auch, hat mich halt interessiert, ob es da auch 
schon fertige Lösungen gibt.

Klaus Wachtler schrieb:
> Zu erreichen auch über die Suchfunktion hier ("Festkommazahlen in Würde"
> oder so ähnlich).
Jupp, siehe hier Beitrag "Festkommazahlen in Würde"
Danke für die Hinweise...

von Hc Z. (mizch)


Lesenswert?

16-Bit-Floats haben schon (manchmal) ihre Berechtigung.  Immerhin lässt 
sich damit eine Genauigkeit von <1% über mehr als 5 Dekaden erzielen. 
In meinem Fall ging es um eine in sehr weiten Grenzen anpassbare 
Temperaturregelung, realisiert mit einem maskenprogrammierten 4-Bitter 
und selbstgeschriebener Floating-Point-Library, die danach noch öfters 
eingesetzt wurde (und wahrscheinlich noch wird).  Also Anwendungen gibt 
es durchaus.

von Klaus W. (mfgkw)


Lesenswert?

delicious_cake schrieb:
> Andererseits gibt es ja die Möglichkeit den float Datentyp zu
> konfigurieren (float.h).

Mit float.h kannst du nicht den Typ verändern, sondern nur seine 
Implementation erfragen.

von delicious_cake (Gast)


Lesenswert?

Klaus Wachtler schrieb:
> Mit float.h kannst du nicht den Typ verändern, sondern nur seine
> Implementation erfragen.

das ließt sich hier:
http://openbook.galileocomputing.de/c_von_a_bis_z/030_c_anhang_b_006.htm

aber ganz anders. Das kommt mir vor, als könnte ich den Typ float 
editieren.

von Karl H. (kbuchegg)


Lesenswert?

delicious_cake schrieb:
> Klaus Wachtler schrieb:
>> Mit float.h kannst du nicht den Typ verändern, sondern nur seine
>> Implementation erfragen.
>
> das ließt sich hier:
> http://openbook.galileocomputing.de/c_von_a_bis_z/030_c_anhang_b_006.htm


Das hier
1
In der Headerdatei <float.h> werden Makros für die Genauigkeit,
2
den Wertebereich und andere Eigenschaften der Datentypen float,
3
double und long double definiert.

heißt nicht, dass du vorgeben kannst, wie sich Floating Point Datentypen 
verhalten soll, sondern die Implementierung stellt dir ein paar #define 
zur Verfügung, mit denen du als Programmierer dich darüber informieren 
kannst, wie die Eigenschaften sind

"werden definiert" bedeutet in C normalerweise:
Es gibt ein paar #define
und nicht: du kannst da festlegen, was du haben willst.

Wenn letzteres möglich ist, dann steht das meistens explizit in der 
Doku: "Man kann hier festlegen, dass ...."

Überleg doch mal: das wäre doch viel zu aufwändig und der Performance 
alles andere als zuträglich, wenn man Floating Point Arithmetik 
algorithmisch so umsetzen muss, dass man alle Fälle, die du dort 
angenommenerweise einstellen kannst, berücksichtigen würde.

Dasselbe isz zb auch bei RAND_MAX der Fall. Die IMplementierung stellt 
dir eine Kennzahl zur Verfügung, mit der der maximale Wert den rand() 
liefern kann, einfach benutzt werden kann. Aber das heißt nicht, dass 
man den so einfach ändern kann. Der Wert ergibt sich aus dem genauen 
Aufbau der rand() Formel. Will man den Wert einstellbar haben, müsste 
man die Formel ändern. Und das könnte sich als trickreich erweisen - 
weil ja der Code in der Library schon vorcompiliert ist.

von delicious_cake (Gast)


Lesenswert?

@ Karl heinz Buchegger:
Danke für deine Erklaerung. Die ist mal sehr einleuchtend. Ich dachte 
mir halt, dass es evtl möglich waere. Einige gute Texas Instruments 
Taschenrechner besitzen naehmlich die Möglichkeit einer Einstellung der 
Rechengenauigkeit. von FIX0 bis FIX 12 oder FLOAT bis FLOAT12.

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.