Gleitkommaberechnung AVR

Gast #1632595
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);
Angehängte Dateien:
#1632620
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
Gast #1632625
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...!?!?
Moderator Persönliche Seite #1632633
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.
#1632644
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
}
Gast #1635364
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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren