Sinusfunktion in C gut implementiert?

Gast #679422
Lesenswert?

Hallo Forum,

da ich Zeitkritisch den Sinus berechnen muss (<200 Takte),
habe ich mir überlegt den Sinus so zu implementieren:

Was haltet ihr von dieser Methode?
1
#define AnzahlinTabelle  eineZahlXY 
2
.
3
.
4
.
5
.
6
signed char sinus(unsigned char p){
7
  if(p>AnzahlinTabelle*2){  //  >180Grad?
8
    return -sinus(p-(AnzahlinTabelle*2));
9
  }
10
  if(p>AnzahlinTabelle){
11
    return sinus((AnzahlinTabelle*2) - p); //175grad => 180-175=05 
12
  }
13
  return tabelle[p];
14
}

-hub
#679464
Lesenswert?

@ hubert (Gast)

>da ich Zeitkritisch den Sinus berechnen muss (<200 Takte),
>habe ich mir überlegt den Sinus so zu implementieren:

>Was haltet ihr von dieser Methode?

Gut, kann man aber noch auf 1/4 von 2*Pi reduzieren. Man hat dann halt 4 
Fallunterscheidungen.

MFG
Falk
Gast #679473
Lesenswert?

Wenn die Berechnung zeitkritisch ist, würde ich auf die Rekursion
verzichten und die Unterteilung der Werte in die vier Quadranten
explizit hinschreiben:
1
signed char sinus(unsigned char p){
2
  if(p>AnzahlinTabelle*3)
3
    return -tabelle[AnzahlinTabelle*4-p];
4
  if(p>AnzahlinTabelle*2)
5
    return -tabelle[p-AnzahlinTabelle*2];
6
  if(p>AnzahlinTabelle)
7
    return tabelle[AnzahlinTabelle*2-p];
8
  return tabelle[p];
9
}

Oder natürlich, wenn genug Speicher da ist, die Tabelle so groß
machen, dass sie alle vier Quadranten umfasst.
#679482
Lesenswert?

@ yalu (Gast)

>Wenn die Berechnung zeitkritisch ist, würde ich auf die Rekursion
>verzichten und die Unterteilung der Werte in die vier Quadranten
>explizit hinschreiben:

Fast richtig. Aber bei dir dauert die Funktion für verschiedene 
Quadranten unterschiedlich lang. Besser so. Binärer Baum.

[c]
signed char sinus(unsigned char p){
  if(p>AnzahlinTabelle*2) {
    if(p>AnzahlinTabelle*3)
      return -tabelle[AnzahlinTabelle*4-p];
    else
      return -tabelle[p-AnzahlinTabelle*2];
  }
  else {
  if(p>AnzahlinTabelle)
    return tabelle[AnzahlinTabelle*2-p];
  else
    return tabelle[p];
  }
}
[c]

>Oder natürlich, wenn genug Speicher da ist, die Tabelle so groß
>machen, dass sie alle vier Quadranten umfasst.

Das kann ja jeder ;-)

MFG
Falk
Gast #679585
Lesenswert?

danke für die Antworten!

inzwischen habe ich mich für die Tabellengröße 45 entschieden:
1
signed char tabelle[]={  0,  4,  9, 13, 28, 22, 26, 31, 35,                              39, 43, 48, 52, 56, 60, 64, 67, 71,
2
                        75, 78, 82, 75, 88, 91, 94, 97,100,
3
                       103,105,108,110,112,114,116,118,119,
4
                       121,122,123,124,125,126,126,127,127,127};
5
.
6
.
7
.
8
signed char sinus(unsigned char p){
9
  if(p>90) {
10
    if(p>135)
11
      return -tabelle[180-p];
12
    else
13
      return -tabelle[p-90];
14
  }
15
  else {
16
  if(p>45)
17
    return tabelle[90-p];
18
  else
19
    return tabelle[p];
20
  }
21
}

Das heißt also 180 entspricht dem Vollwinkel(360°).

-hub

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