mikrocontroller.net

Forum: Digitale Signalverarbeitung / DSP Float ungenauigkeit bei iir Filter unterschiede visual studio und CC Studio von TI


Autor: andi 1981 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
Ich arbeite testweise mit dem Visual Studio 2005

Ich habe folgenden 10 poligen IIR Filter mit 2 Koeffizienten.

int main()

{
  float koef1=0.92; //filter koeffizient 1
  float koef2=1-0.92; //Filter koeffizient 2
  
  //zwischenspeicher
  static float fa_wert1=0;
  static float fa_wert2=0;
  static float fa_wert3=0;
  static float fa_wert4=0;
  static float fa_wert5=0;
  static float fa_wert6=0;
  static float fa_wert7=0;
  static float fa_wert8=0;
  static float fa_wert9=0;
  static float fa_wert10=0;
  
  long e_wert=100000000; //eingagnswert
  long fa_erg=0;  //ergebnis

  for(;;)
  {
    fa_wert1 = koef1 * fa_wert1 + koef2 * e_wert;
    fa_wert2 = koef1 * fa_wert2 + koef2 * fa_wert1;
    fa_wert3 = koef1 * fa_wert3 + koef2 * fa_wert2;
    fa_wert4 = koef1 * fa_wert4 + koef2 * fa_wert3;
    fa_wert5 = koef1 * fa_wert5 + koef2 * fa_wert4;
    fa_wert6 = koef1 * fa_wert6 + koef2 * fa_wert5;
    fa_wert7 = koef1 * fa_wert7 + koef2 * fa_wert6;
    fa_wert8 = koef1 * fa_wert8 + koef2 * fa_wert7;
    fa_wert9 = koef1 * fa_wert9 + koef2 * fa_wert8;
    fa_wert10 = koef1 * fa_wert10 + koef2 * fa_wert9;
    fa_erg = (long)fa_wert10;
    printf("e=%d\n",fa_erg);
  }
}


Wenn ich nun als Eingangswert fest immer 100 000 000 nehme kommt das 
Ergebnis nie an 100 Millionen ran sondern bleibt fest bei 99 999 760. 
Ich denke das liegt an der Ungenauigkeit von Float.

Frage 1 kann mir hierzu jemand mehr sagen?

Wenn ich dasselbe mit dem CC-Studio und einem DSP von TI (TMS320f2812) 
mache,  erhalte ich nie mehr als 99 999 048

Diese Ungenauigkeit ist mir einfach zu groß. Laut Datenblatt arbeitet 
der TI Prozessor nach IEEE 32 Bit

Frage 2 Ich denke Visual Studio doch sicher auch oder?

Frage 3 Warum dann die großen Unterschiede?

Frage 4 kann ich die ungenauigkeit durch kompiler einstellungen 
verringern oder bleibt mir nur der weg über „long double“ was aber 
einfach viel zu lange dauert bis er die Rechnung gemacht hat.

Vielen dank für eure Antworten

Autor: Freizeitbastler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

verzeih' meine Ignoranz. Wenn ich ins Datenblatt schaue sehe ich nur 32 
Bit Festkomma-Arithmetik. Demnach wäre float auf dem Prozessor durch 
eine Lib realisiert. Das ist schon langsam genug. Striktes IEEE kostet 
meistens noch was extra an Zeit und wird deswegen gerne eingespart.

Gruß, Peter

PS: Linux+GCC hat dasselbe Ergebnis wie Dein Visual Studio.

Autor: Detlef _a (detlef_a)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Lieber so:

static float fa_wert1=0.0;

float hat 23 Bit Mantisse: 2^23 ~ 10^6.9 , also hat 32 Bit float 7 
gültige Ziffern.

>>Frage 2 Ich denke Visual Studio doch sicher auch oder?
Antwort gibt Dir sizeof(float), ist aber vermutlich 4 Byte.

Der Tiefpaß-hack T=(1-eps)*T + u kann bei Integerrechnung ( z.B: 
T=T-(T>>20)+u;) tückisch sein, bei zu geringen Bitbreiten wird die 
Sprungantwort, die eigentlich e-Fkt sein sollte, durch Geradenstücke 
schlecht approximiert, da muß man aufpassen. Ob das bei niedrigbittigem 
float auch so ist weiß ich allerdings nicht.

>>zu lange dauert bis er die Rechnung gemacht hat.
In 32 Bit integer rechnen, ist genauer und schneller. 0.92 ~ 471/512

Cheers
Detlef

Autor: Freizeitbastler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
==Klugscheißermodus an==
In den 4 Bytes eines IEEE Floats werden 23 Bits der Mantisse abgelegt. 
Die Mantisse ist aber effektiv 24 Bit lang, weil der Exponent immer so 
gewählt wird, dass das vordere Bit eine 1 ist und nicht gespeichert 
werden braucht.

sizeof(float) == 4 ist notwendig aber nicht hinreichend für IEEE Float 
Arithmetik. Das beste Beispiel liefert der OP: Auf dem DSP kommt was 
anderes raus als bei IEEE Float.
==Klugscheißermodus aus==

Ich bevorzuge auch die Festkomma-Rechnung.

Gruß, Peter

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.