Forum: Mikrocontroller und Digitale Elektronik Gleitkommaberechnung AVR


von Chriss (Gast)


Angehängte Dateien:

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.
1
#typedef u8 unsigned char
2
u8 R, G, B;
3
  u8 hi = (u8) ((float)hue / 60.0F);
4
  float f = (((float)hue) / 60.0F) - hi;
5
  float V = (((float)value)/100.0F);
6
  float S = (((float)sat)/100.0F);
7
  float p=V*(1.0F-S);
8
  float q=V*(1.0F-(S*f));
9
  float t = V*(1.0F-S*(1.0F-f));
10
  
11
  switch(hi)
12
  {
13
    case 0:
14
    case 6:
15
    R = (u8) (V*255.0f);
16
    G = (u8) (t*255.0f);
17
    B = (u8) (p*255.0f);
18
19
      break;
20
    case 1:
21
    R = (u8) (q*255.0f);
22
    G = (u8) (V*255.0f);
23
    B = (u8) (p*255.0f);      
24
      break;
25
    case 2:
26
    R = (u8) (p*255.0f);
27
    G = (u8) (V*255.0f);
28
    B = (u8) (t*255.0f);
29
      break;
30
    case 3:
31
        R = (u8) (p*255.0f);
32
    G = (u8) (q*255.0f);
33
    B = (u8) (V*255.0f);
34
      break;
35
    case 4:
36
        R = (u8) (t*255.0f);
37
    G = (u8) (p*255.0f);
38
    B = (u8) (V*255.0f);
39
      break;
40
    case 5:
41
        R = (u8) (V*255.0f);
42
    G = (u8) (p*255.0f);
43
    B = (u8) (q*255.0f);
44
      break;
45
  }

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
1
float S = (((float)sat)/100.0F);

von Falk B. (falk)


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

von Chriss (Gast)


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...!?!?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


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.

von 900ss (900ss)


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.

1
int main( void )
2
{
3
4
  float a,b,c;
5
6
  a = 100.F;
7
  b = 100.F;
8
  c = 0.F;          // c = 0.
9
  c = a / b;        // c = 1.0
10
11
  c = c / 0.25;     // c = 4.0
12
13
  c = c / 3.F;      // c = 1.3333334
14
15
16
  while(1)
17
  ;
18
19
}

von Chriss (Gast)


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

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.