Mathebibliothek für STM8S

Gast #4968609
Lesenswert?

sdcc/include/math.h bietet:
1
/* Trigonometric functions */
2
float sinf(float x) _FLOAT_FUNC_REENTRANT;
3
float cosf(float x) _FLOAT_FUNC_REENTRANT;
4
float tanf(float x) _FLOAT_FUNC_REENTRANT;
5
float cotf(float x) _FLOAT_FUNC_REENTRANT;
6
float asinf(float x) _FLOAT_FUNC_REENTRANT;
7
float acosf(float x) _FLOAT_FUNC_REENTRANT;
8
float atanf(float x) _FLOAT_FUNC_REENTRANT;
9
float atan2f(float x, float y);
10

11
/* Hyperbolic functions */
12
float sinhf(float x) _FLOAT_FUNC_REENTRANT;
13
float coshf(float x) _FLOAT_FUNC_REENTRANT;
14
float tanhf(float x) _FLOAT_FUNC_REENTRANT;
15

16
/* Exponential, logarithmic and power functions */
17
float expf(float x) _FLOAT_FUNC_REENTRANT;
18
float logf(float x) _FLOAT_FUNC_REENTRANT;
19
float log10f(float x) _FLOAT_FUNC_REENTRANT;
20
float powf(float x, float y);
21
float sqrtf(float a) _FLOAT_FUNC_REENTRANT;
22

23
/* Nearest integer, absolute value, and remainder functions */
24
float fabsf(float x) _FLOAT_FUNC_REENTRANT;
25
float frexpf(float x, int *pw2);
26
float ldexpf(float x, int pw2);
27
float ceilf(float x) _FLOAT_FUNC_REENTRANT;
28
float floorf(float x) _FLOAT_FUNC_REENTRANT;
29
float modff(float x, float * y);
Gast #4969662
Lesenswert?

> Wo finde ich die?

stm8/lib

Eigentlich sollte hier mal was stehen.
Aber wer zu faul ist, die Doku* mal selber zu lesen...
Dem schreib ich das hier nicht nochmal ab.



*) doc/EWstm8_DevelopmentGuide.pdf
#4969804
Lesenswert?

... wenn du die math - library nicht einbinden magst, vielleicht hilft 
dir das ?!?

Sinus / Cosinus über Taylorreihenentwicklung. Ich hatte es hier vor 
geraumer Zeit auch davon (allerdings primär für einen STM32F030). Ein 
Forumsmitglied hatte hier eine geniale Festkommabibliothek gepostet 
(nicht von ihm), die ich allerdings noch nicht auf einen STM8 portiert 
habe (gibt Schwierigkeiten bzgl. int32 Variablen).

Die folgenden Funktionen funktionieren auf STM8 und MCS51:
1
/* --------------------------------------------------------
2
     wenn stdarg.h NICHT eingebunden ist, dann ist die
3
     Auskommentierung fuer abs aufzuheben !
4
   -------------------------------------------------------- */
5
/*
6
float abs(float value)
7
{
8
  if (value< 0.0f) return (value * -(1.0f));
9
           else return value;
10
}
11
*/
12

13
#define MY_PI     3.14159265359f
14

15
/* --------------------------------------------------------
16
   tiny_pow
17

18
   bestimmt den Wert fuer value hoch n ( value ^ n)
19
   Der Exponent n muss (leider) eine Ganzzahl (integer)
20
   sein
21
   -------------------------------------------------------- */
22
float tiny_pow(int n, float value)
23
{
24
  float tmp;
25
  int   i;
26

27
  tmp= value;
28
  for (i= 0; i < n-1; i++)
29
  {
30
    tmp= tmp*value;
31
  }
32
  return tmp;
33
}
34

35
/* --------------------------------------------------------
36
   tiny_sin
37

38
   bestimmt den Sinus von value im Bogenmass. Die Be-
39
   rechnung erfolgt mittels Taylorreihe
40
   Eine Umrechnung in Grad kann mittels:
41
      sin(wert * (MY_PI / 180.0f) erfolgen
42
   -------------------------------------------------------- */
43
float tiny_sin(float value)
44
{
45
  float degree;
46
  float p3;
47
  float p5;
48
  float p7;
49
  float sinx;
50

51
  int   mflag= 0;
52

53
  while (value > (2*MY_PI)) value -= (2*MY_PI);
54
  if (value > MY_PI)
55
  {
56
    mflag= - 1;
57
    value -= MY_PI;
58
  }
59

60
  if (value > (MY_PI /2)) value = MY_PI - value;
61

62
  degree= value;
63

64
  p3 = tiny_pow(3, degree);
65
  p5  = tiny_pow(5, degree);
66
  p7  = tiny_pow(7, degree);
67

68
  // Taylor-Reihenentwicklung
69
  // 6 = fak(3); 120 = fak(5); 5040= fak(7)
70
  sinx= (degree - (p3/6.0f) + (p5/120.0f) - (p7/5040.0f));
71

72
  if (mflag) sinx = sinx * (-1);
73

74
  return sinx;
75
}
76

77
/* --------------------------------------------------------
78
   tiny_cos
79

80
   Bestimmt den Cosinus von Value im Bogenmass
81
   -------------------------------------------------------- */
82
float tiny_cos(float value)
83
{
84
  return tiny_sin(value - (MY_PI / 2.0f)) * -1.0f;
85
}
Gast #4970387
Lesenswert?

Na, das mit dem "tiny_pow" ist aber so ziemlich die ärgste 
Resoucenverschwendung, Stichwort Horner-Schema. Spart VIELE 
Multiplikationen gegenüber der Trivial-Variante bei der 
Polynomauswertung:
a_n*x^n+a_{n-1}*x^{n-1}+...+a_1*x+a_0
=(...(a_n*x+a_{n-1})*x+a_{n-2})*x+a_{n-3})...)*x+a_0
Da wird also nur fortwährend mit x multipliziert und der 
nächstniedrigere Koeffizient dazu addiert.
Wenn man weiß, dass nur ungerade (oder nur gerade) Potenzen auftauchen, 
modifiert man das natürlich, dass man laufend mit x^2 multipliziert.
Die Zahl der Multiplikationen ist bei der Trivial-Variante von der 
Größenordnung n^2, beim Horner-Schema nur n.

Außerdem: Taylor-Entwicklung ist nicht so das Gelbe vom Ei, wenn man ein 
relativ großes Intervall betrachtet. In der Nähe des Entwicklungspunktes 
(hier: 0) zwar nicht schlecht, aber die Qualität sinkt mit zunehmendem 
Abstand rapide ... Und [0,pi] ist schon ziemlich groß.
(Übrigens ist das oben nicht "mit Taylor-Reihe", sondern "mit 
Taylor-Polynom".)

Besser: Entwicklung nach Legendre- oder Tschebyschow-Polynomen, damit 
erzielt man eine halbwegs gleichmäßige Approximationsgüte auch bei einem 
längeren Intervall. Und es kommt trotzdem wieder ein Polynom (auch 
ungerade bzw. beim Kosinus gerade) heraus, der Rechenaufwand ist also 
derselbe.

Die Implementierung oben liefert übrigens bei negativen Winkeln ... ?!
Und wenn schon Taylor, sollte man ein möglichst kleines Intervall 
nehmen, es böte sich also an, auch noch die Symmetrie von [0,pi/2] zu 
[pi/2,pi] zu nutzen.
#4970733
Lesenswert?

... absolut alles richtig was du sagst.

Allerdings hatten diese Funktionen schlicht funktioniert und es war noch 
ausreichend Platz.

Grundsätzlich war das etwas schnelles und bei anderen Controllern hatte 
ich die math hinzugelinkt.

Dann, wenn der Platz gering wird, verwende ich die Festkomma-Software 
die hier ein Forumsmitglied gepostet hat.

Bei der Taylorreihenentwicklung sieht man allerdings auch sehr schön, 
wie das aufgebaut ist... und (ich weiß das ist nicht wirklich ein 
Argument) die Quelldateien bleiben schön klein und übersichtlich !

(Allerdings - wie du absolut richtig angemerkt hast: ungenau und 
resourcenverschwendend)

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