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
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
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.
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_754http://de.wikipedia.org/wiki/Minifloat
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.
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.
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?
"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...
@ 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)
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...
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.
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.
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.
@ 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.