Fixpointzahl für Sinus

Gast #2512679
Hallo,

ich habe ein Problem mit, wie im Titel schon erwähnt, mit Fikommazahlen. 
Ich verwende das Luminary LMS38962 Microcontroller Board von TI. Dabei 
verwende ich die miteglieferte DriverLib. In dieser ist eine Funktion 
für den Sinus definiert. Allerdings wird für die Berechnung dieser ein 
Fixkommawert des Datentyps unsigned long benötigt (0.32). Dieser gibt 
den Winkel in Prozent an, also 2*pi = 100% = 0.999999999...
Soviel ich aber weiß (vielleicht ist dieses vermeintliche Wissen falsch) 
werden die Werte aber als Gleitkomma (also mit Mantisse und Exponent) 
abgespeichert.

Leider bin ich nicht in der Lage den Gleitkommawert in einen 
Fixkommawert umzuwandeln, oder direkt einen solchen zu erzeugen (wär 
noch viel besser). Habe schon die ganze Allwissende Müllhalde 
abgeklappert, jedoch ohne Erfolg.

Ich hoffe ihr könnt mir weiterhhelfen.

mfg Graph Oszillo
Gast
Graph Oszillo schrieb:
> Leider bin ich nicht in der Lage den Gleitkommawert in einen
> Fixkommawert umzuwandeln

Woran scheitert es denn?
Auf einem µC ist es oft vorteilhaft Fixkommazahlen auf Basis vom 
2er-System zu verwenden. Welche Auflösung brauchst du für deine 
Fixkommazahlen?
(Firma: Atelier Klippel)
Uh, Ernsthaft?

Also, nehmen wir mal das Dezimalsystem. Was ergibt sich aus:

0,09 + 0,01?

Und nun mal das Hexadezimalsystem. Was ergibt sich aus:

0x0F + 0x01?

Da der Wertbereich deiner Angabe nach sich auf 0,0 - 0,999~ erstreckt, 
sagen wir mal bis 1,0, und Du nun 32 Bit hast... Wenn die 32 Bit nun die 
Nachkommastellen angeben, so ist das 0xFFFFFFFF was dann 0.999~ 
entsprechen soll. Dieser Hex-Wert entspricht dezimal 4.294.967.295. Die 
1,0 wäre dann 4.294.967.296 oder in Hex 100000000. Klickt es nun?

Anders ausgedrückt: Du dividierst den Fixed-Point von "0,32" Bit ganz 
einfach durch 4.294.967.296 um einen Fließkommawert im Bereich 0,0 - 
0,999~ zu erhalten. Wenn Du aber den Wertbereich 0,0 - 1,0 haben willst, 
dann dividierst Du ganz einfach durch 4.294.967.295.

Grüße,

Chris

Edit: Oder wenn Du den 32-Bit Fixed-Point Wert haben willst dann 
dividierst Du die 4.294.967.296 oder 4,294,967,295 einfach durch den 
Fließkommawert (der den Bereich 0,0 bis 0,999~ oder 1,0 haben muss).
Das ist genau das Gleiche wie beim Ergebnis eines AD-Wandlers. Da ist 
die Zahl nur nicht so groß.

10-Bit-ADC skaliert auf Uref:
U = Uref * ADC_Value / 2^10 (=1024)

Dein Sinus skaliert auf 1:
sin = (1 * )Value / 2^32 (= s.o.)

Oder auf 255 zur Ausgabe auf einen 8-Bit DA-Wandler
DA-Value = 255 * Value / 2^32

mfg.
Gast
Wieso braucht man eigentlich eine Tabelle mit dem Typ unsigned long, 
wenn man Zahlen aus dem Bereich 0,000 .. 0,999 - also drei Stellen im 
Dezimalsystem -  als Fixkommawerte ablegen möchte. Um die Zahlen 
darzustellen, reichen 10-Bit, d.h. 22-Bit sind völlig nutzlos.

Welche Genauigkeit muß denn die Tabelle nun wirklich haben, d.h. wie 
sauber muß der Sinus sein?
Werner schrieb:
> Welche Genauigkeit muß denn die Tabelle nun wirklich haben, d.h. wie
> sauber muß der Sinus sein?
So sauber wie möglich. Also unendlich viele Werte. Wie bei Analog.
Das geht aber digital nicht. Das ist immer endlich. Also rechnet man auf 
einem 32-Bit-Rechner auch mit 32 Bit. Damit rechnet er sowieso.
Und zwar solange  wie möglich. Das Umrechnen in eine Dezimalzahl ist 
erst der letzte Schritt und nur für uns. Rechnen kann der Controller 
besser binär. Und die Rundungsfehler bleiben bei 32 Bit klein.

Auf einem 8-Bitter, wo das zum zeitaufwendigen K(r)ampf wird, überlegt 
man sich, ob man so viele Werte wirklich braucht, wenn man sie z.B. auf 
einen 10-Bit DAC ausgeben will.

mfg.
(Firma: Atelier Klippel)
Thomas Eckmann schrieb:
> Auf einem 8-Bitter, wo das zum zeitaufwendigen K(r)ampf wird, überlegt
> man sich, ob man so viele Werte wirklich braucht, wenn man sie z.B. auf
> einen 10-Bit DAC ausgeben will.
>
> mfg.

Wobei man auch da beachten muss das es in gewissen Situationen ein paar 
gute Tricks gibt. Viele µC haben einen Hardware-Multiplier, also eine 
Einheit die in meistens einem Takt eine Multiplikation machen kann. 
Damit kann man aber auch auch eine Division machen. Natürlich nur unter 
gewissen Bedingungen.

Grüße,

Chris
(Firma: Atelier Klippel)
Werner schrieb:
> Wieso braucht man eigentlich eine Tabelle mit dem Typ unsigned long,
> wenn man Zahlen aus dem Bereich 0,000 .. 0,999 - also drei Stellen im
> Dezimalsystem -  als Fixkommawerte ablegen möchte. Um die Zahlen
> darzustellen, reichen 10-Bit, d.h. 22-Bit sind völlig nutzlos.
>
> Welche Genauigkeit muß denn die Tabelle nun wirklich haben, d.h. wie
> sauber muß der Sinus sein?

Falls Du dich damit auf mein Beispiel beziehst dann beachte bitte das 
ich nicht drei Nachkommastellen angegeben habe, sondern z.B. 0,999~, 
wobei das ~ dann "unendlich" repräsentiert.

Grüße,

Chris
Gast
Thomas Eckmann schrieb:
> So sauber wie möglich. Also unendlich viele Werte. Wie bei Analog.

"So sauber wie möglich" kann kein Mensch bezahlen und ist meistens nicht 
wirklich nötig.

Was hat die Sauberkeit des Sinus mit "Analog" und "unendlich viele 
Werte" zu tun. Als Kriterium würde man eher sowas wie SNR oder Dämpfung 
der Oberwellen erwarten. Aber vielleicht kann sich unser Graph mal zu 
seinem Problem äußern.
Gast
Vielen Dank an alle!

Von mir aus müsste der Wert nicht mal auf drei Nachkommastellen genau 
sein, da ich diesen nur auf dem 128x96 Pixel großen Display zeichnen 
werde. Allerdings rechnet diese Sinusfunktion sowieso keine Werte selbst 
aus. Sie hat die Werte eines viertel Sinus (90°) in einem Array als 0.16 
Fixpoint unsigned short gespeichert, und legt diese Kurve mehrmals 
aneinander. Ausgegeben wird ein 16.16 Fixpoint Long.

Bezüglich der Umwandlung hätte ich noch eine Frage: Wenn ich einen 16.16 
Fixpoint wieder auf Floatingpoint umwandeln will, muss ich dann einfach 
durch 2^16 dividieren?

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 14 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

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.