Forum: Digitale Signalverarbeitung / DSP / Machine Learning DSP Normalisierung Float und Konvertierung Fixed Point


von Matthias G. (gille)


Lesenswert?

Hallo zusammen,

Ich bin recht neu bei der DSP-Programmierung und habe ein vermutlich 
sehr einfaches Problem:

Ich programmiere in C und will später mit einem STM32Disco mit 16Bit ADC 
arbeiten. Momentan beschäftige mich gerade mit Festkommaarithmetik.

Zum Probieren habe ich zunächst ein float array welches ich mittels 
Schleife und Sinusfunktion fülle.

Das ganze will ich dann normieren indem ich jeden Wert durch den 
Betragsmäßig größten Teile.

Ist der größte Betrag positiv bekomme ich dann als größten Wert eine 1. 
Nun ist es ja aber so dass das fractional Format 1.15 von 
-1<...0.999999... geht und nicht bis +1. Wobei das erste Bit ja das 
Vorzeichen repräsentiert und der Rest die Nachkommastellen 1/2, 1/4 usw.

Wenn ich also diese float-Werte in short konvertiere bekomme ich für den 
Spitzenwert statt 32767 (0b0111 1111 1111 1111)den Wert -32768 (0b1000 
0000 0000 0000).

Es ist mir auf Bit-Ebene klar wieso das passiert, da ich ja 
(short)(1.0*(1<<15)) rechne.

Deshalb meine Fragen:
Muss ich was bei der Normierung ändern um der Definition des Fractional 
Formats gerecht zu werden?
Wie wäre das "Lehrbuchgerechte" vorgehen bei einer solchen 
Konvertierung?

Danke.
Gruß Gille

von Martin O. (ossi-2)


Lesenswert?

Eine Möglichkeit wäre, die Werte quasi vorher mit 32767/32768 zu 
multiplizieren, damit alle Werte ins 1.15 Format passen. Oder Du 
"rundest" die 1.0 zi 0.111111111111111111111111 mit kleinem Fehler.

von Matthias G. (gille)


Lesenswert?

Ok, Danke.

Das machst Sinn bei meinem Problem. Wenn ich aber später echtzeitfähig 
arbeite kann ich mir doch sicher keine Mutiplikation und anschließende 
Division jedes einzelnen Wertes leisten oder?

Der ADC wird mir ja sicher schon short-Werte mit Offset raus geben (0 
=-1V und 65535=+1V oder so). Damit kann ich ja dann direkt arbeiten.

Wenn ich allerdings einen Datenstrom bekomme der float-Werte enthält 
komme ich doch sicher schnell an die Grenze der Geschwindigkeit, weil 
der DSP ja eben keine Gleitkommaarithmetik beherrscht bzw nur langsam.

Deshalb ist ja die Idee so schnell wie möglich auf fixed point zu 
wechseln und die Rechnerei dann damit zu machen.

Oder hab Ich da grundlegend was falsch verstanden?

von Walter T. (nicolas)


Lesenswert?

Matthias G. schrieb:
> STM32Disco

Welches? Die M4 sind erstaunlich schnell bei Float32. Ich habe gestern 
für Spaß einen recht multiplikationslastigen Algorithmus erst in float 
und dann in Festkomma umgestellt, und erstaunt festgestellt, daß es 
praktisch keinen Unterschied in der Laufzeit gab.

Bei 16-Bit-Festkomma-Zahlen sollte das etwas anders aussehen, weil kein 
64-Bit-Zwischenergebnis bei Multiplikationen notwendig ist. Aber der 
Unterschied bleibt mittlerweile erstaunlich klein.

von Mampf F. (mampf) Benutzerseite


Lesenswert?

Matthias G. schrieb:
> Ich programmiere in C und will später mit einem STM32Disco mit 16Bit ADC
> arbeiten. Momentan beschäftige mich gerade mit Festkommaarithmetik.

Wenn das ein STM32Disco mit Cortex M4 zB ist, brauchst du bezüglich 
Festkommaarithmetik nichts machen ... Das wäre langsamer als gleich die 
eingebaute FPU zu verwenden.

Die meisten FPU-Befehle brauchen nur 1 Taktzyklus - außer Division 
(glaube 12 oder 13) und noch ein anderer ... Aber Multiplikation, 
Addition usw alles nur 1 Takt.

Hatte vor kurzem einen Dynamik-Kompressor auf Festpunkt umgebaut und war 
erstaunt, dass der dann langsamer war als alles einfach auf Float zu 
lassen.

: Bearbeitet durch User
von Detlef _. (detlef_a)


Lesenswert?

Ja, schließe mich Ossi-2 an. Du normierst auf 32767 bis -32767, also 
2^15-1 bis -(2^15-1). Die Interpretation als 1.15 ist in Matlab Notation
von sum(2.^(-15:-1)) bis -sum(2.^(-15:-1)), mit

sum(2.^(-15:-1))=0.999969482421875=1-2^(-15)

Bei int16_t ist es lästig, dass der größte Wert 32767 und der kleinste 
-32768 ist, also 'unsymmetrisch'. Muss aber so sein, weil es ja eine 
gerade Anzahl Zahlen in int16_t gibt und die 0 auf noch beigehört ;))))

Und richtig ist auch, dass fixed point bei den Cortexen mit FPU keinen 
Sinn mehr macht.

math rulez!
Cheers
Detlef

: Bearbeitet durch User
von Mampf F. (mampf) Benutzerseite


Lesenswert?

Nachtrag:

Leider darf ich den Link nicht posten, weil die 
oberschlaue-Foren-Software meint, das wäre Spam (.cn im Link).

Hier steht noch mehr zur FPU:

AN4044
Application note
Floating point unit demonstration on STM32 microcontrollers

von Matthias G. (gille)


Lesenswert?

Ok, vielen Dank.

Ich werde das mal umsetzen und schauen wie mein Professor das so findet 
:)

von --- (Gast)


Lesenswert?

"Richtige" Festkomma-DSPs haben gegenüber den Registern mehr Bits
in ihren Akkumulatoren und können daher nicht so einfach überlaufen
oder sättigen.
Skalieren/Normalisieren tut man da häufig nur am Ende eines
Berechnungsalgorhitmus, wenn überhaupt.
Nebenbei können typische "richtige" DSP auch parallel noch
die nötigen Adreßoperationen für den Zugriff auf Daten und
Koeffizienten durchführen.

Das "ARMe" einiges an DSP-typischen Operationen anbieten,
was bei der Umsetzung hilfreich ist, sollte nicht darüber
hinwegtäuschen, dass sie eben doch keine "richtigen" DSPs sind.

Und, um die jeweiligen Stärken eines DSPs zu nutzen, wird
man auch heute noch auf Assembler zurückgreifen (müssen).

Tut mir ja leid für dich, aber auch mit einem M4-ARM steigst
du nicht in die typische Programmierung von DSPs ein.
Du kratzt allenfalls ein wenig an deren Algorithmen herum...

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.