mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Gleitkommaberechnung AVR


Autor: Chriss (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Habe bei der Gleitkommaberechnung beim ATMEGA128 Probleme...
Habe eine Routine um vom HSV Farbraum in den RGB Farbraum umzurechnen.
Leider sind die Ergebnisse teilweise sehr ungenau.
#typedef u8 unsigned char
u8 R, G, B;
  u8 hi = (u8) ((float)hue / 60.0F);
  float f = (((float)hue) / 60.0F) - hi;
  float V = (((float)value)/100.0F);
  float S = (((float)sat)/100.0F);
  float p=V*(1.0F-S);
  float q=V*(1.0F-(S*f));
  float t = V*(1.0F-S*(1.0F-f));
  
  switch(hi)
  {
    case 0:
    case 6:
    R = (u8) (V*255.0f);
    G = (u8) (t*255.0f);
    B = (u8) (p*255.0f);

      break;
    case 1:
    R = (u8) (q*255.0f);
    G = (u8) (V*255.0f);
    B = (u8) (p*255.0f);      
      break;
    case 2:
    R = (u8) (p*255.0f);
    G = (u8) (V*255.0f);
    B = (u8) (t*255.0f);
      break;
    case 3:
        R = (u8) (p*255.0f);
    G = (u8) (q*255.0f);
    B = (u8) (V*255.0f);
      break;
    case 4:
        R = (u8) (t*255.0f);
    G = (u8) (p*255.0f);
    B = (u8) (V*255.0f);
      break;
    case 5:
        R = (u8) (V*255.0f);
    G = (u8) (p*255.0f);
    B = (u8) (q*255.0f);
      break;
  }

Wie gut kommt der AVR mit der Gleitkommaberechnung zusammen?
Sollte ich vielleicht das ganze mit double anstatt von float probieren?
Kann man diese Berechnung vielleicht irgendwie vereinfachen?

Probleme gibt es eigentlich bei allen Berechnung bezüglich der 
Genauigkeit
Hier bei dieser Berechnung kommt z.B. wenn sat=100 gesetzt ist nicht 
1.00 als Ergebnis heraus sondern teilweise 1.14 oder sonst irgendwas 
aber meißtens nicht genau 1
float S = (((float)sat)/100.0F);

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Chriss (Gast)

>Wie gut kommt der AVR mit der Gleitkommaberechnung zusammen?

So gut wie es der Standard vorschreibt.

>Sollte ich vielleicht das ganze mit double anstatt von float probieren?

Nein, beim AVR ist double auch nur ein float mit 32 Bit.

>Kann man diese Berechnung vielleicht irgendwie vereinfachen?

Keine Ahnung.

>Probleme gibt es eigentlich bei allen Berechnung bezüglich der
>Genauigkeit

hast du deine Funktionen mal auf dem PC mit einem Compiler getestet?

>Hier bei dieser Berechnung kommt z.B. wenn sat=100 gesetzt ist nicht
>1.00 als Ergebnis heraus sondern teilweise 1.14 oder sonst irgendwas
>aber meißtens nicht genau 1

Dann liegt der Fehler zu 99% in deiner Software. Soooo ungenau ist Float 
nie und nimmer.

MfG
Falk

Autor: Chriss (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Falk, danke für deine Kommentare...

>hast du deine Funktionen mal auf dem PC mit einem Compiler getestet?

Ich habe das ganze mit dem JTAG auf meinem System getestet.
Wenn bei einer division von 100.0f / 100.0f nicht genau 1.0 herauskommt 
sondern 1.14, also um 2 10tel um 1 herum schwankt dann kann irgenwas 
nicht passen...!?!?

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Chriss schrieb:

> Wenn bei einer division von 100.0f / 100.0f nicht genau 1.0 herauskommt
> sondern 1.14, also um 2 10tel um 1 herum schwankt dann kann irgenwas
> nicht passen...!?!?

Ja, 6...7 Dezimalstellen Genauigkeit kannst du erwarten.

Denk dran, dass der Compiler schon auch mal Zwischenergebnisse nach
eigenem Gutdünken optimiert oder zusammenfasst.

Autor: 900ss D. (900ss)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Folgendes Beispiel hab ich grad mal im Simulator für AT128 getestet.
Funktioniert wie erwartet. Habe in meiner Lötstation den Regler auch mit 
float implementiert. Funktioniert auch auf einem ATMEGA644.

int main( void )
{

  float a,b,c;

  a = 100.F;
  b = 100.F;
  c = 0.F;          // c = 0.
  c = a / b;        // c = 1.0

  c = c / 0.25;     // c = 4.0

  c = c / 3.F;      // c = 1.3333334


  while(1)
  ;

}

Autor: Chriss (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für eure kommentare, muss mich ein bisschen spielen und sehen wie 
ich das beheben kann.. irgendwas scheint nicht zu passen.

Wenn ich weiß was es war, lasse ich es euch wissen!
Danke nochmal

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.