mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Sinusfunktion in C gut implementiert?


Autor: hubert (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

#define AnzahlinTabelle  eineZahlXY 
.
.
.
.
signed char sinus(unsigned char p){
  if(p>AnzahlinTabelle*2){  //  >180Grad?
    return -sinus(p-(AnzahlinTabelle*2));
  }
  if(p>AnzahlinTabelle){
    return sinus((AnzahlinTabelle*2) - p); //175grad => 180-175=05 
  }
  return tabelle[p];
}

-hub

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: yalu (Gast)
Datum:

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

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

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast recht. Damit ist die Berechnung im worst Case eine Abfrage
schneller. Hatte auch die Idee, aber erst, nachdem ich den Code schon
getippt hatte ;-)

Autor: hubert (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
danke für die Antworten!

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

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

-hub

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
AnzahlinTabelle würde ich aber drin lassen und als #define schreiben. 
Macht den Code einfach wiederverwendbar.

MfG
Falk

Autor: Μαtthias W. (matthias) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

oder noch besser gleich mit sizeof arbeiten.

Matthias

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.