Mittelwert über 3 Werte bilden

Gast #862082
Hallo,

ich möchte einen Mittelwert über 3 Werte bilden, jedoch habe ich einen 
Fehler. Der Wert ist zu gering. Kann mir jemand auf die Sprünge helfen?
1
#define INTEGRAL 3
2

3
float integralWert(float Value)
4
{
5
  float  iValue = 0;
6
  static float lastValue[INTEGRAL];
7
  static u08 count;
8

9
  lastValue[count++] = Value;
10
  count %= INTEGRAL;
11
  iValue = (Value - lastValue[(count + INTEGRAL - 2) %INTEGRAL])/INTEGRAL;
12
  return(iValue);
13
}
Gast #862100
Das sieht sehr komisch aus. Versuchs mal so. Habs aber nicht getestet:
1
#define INTEGRAL 3
2

3
float integralWert(float i_flInValue)
4
{
5
  //-- declare locals --------------------------
6
         float  _flClrValue        = 0;
7
  static float  _flSum             = 0;
8
  static float  _flArray[INTEGRAL];
9
  static u08    _u8Count           = 0;
10
  static u08    _u8FillLevel       = 0;
11
  //-- fill into array -------------------------
12
  if ( _u8FillLevel != 0 )  _flClrValue = _flArray[count]
13
  if ( _u8FillLevel < INTEGRAL )
14
  {
15
    _u8FillLevel++;
16
   _flSum += i_flValue;
17
  }
18
  else
19
  {
20
    _flSum = ( _flSum - _flClrValue + i_flValue );
21
  }
22
  _flArray[count] = i_flInValue;
23
  count = ( (count+1) % INTEGRAL );
24
  //-- calculate ------------------------------
25
  return ( _flSum / _u8FillLevel );
26
}
Gast #862121
Dein iValue muss auch static sein.
Und die Zuweisung muss so aussehen: iValue += (Value - lastVal ......

D.h. du nimmst deinen "alten" Mittelwert, ziehst den (ältesten 
Wert)/INTEGRAL ab und addierst den (neusten Wert)/INTEGRAL und erhältst 
somit den neuen Mittwelwert über 3 Werte.

Sieht dann so aus:
1
#define INTEGRAL 3
2

3
float integralWert(float Value)
4
{
5
  static float  iValue = 0;
6
  static float lastValue[INTEGRAL];
7
  static u08 count;
8

9
  lastValue[count++] = Value;
10
  count %= INTEGRAL;
11
  iValue += (Value - lastValue[(count + INTEGRAL - 2) %INTEGRAL])/INTEGRAL;
12
  return(iValue);
13
}

Ich würds aus Übersichtlichkeitsgründen aber bisschen anders machen, und 
zwar so:
1
#define INTEGRAL 3
2

3
float integralWert(float Value)
4
{
5
  static float  iValue = 0;
6
  static float lastValue[INTEGRAL];
7
  static u08 count;
8

9
  iValue -= lastValue[count]/INTEGRAL;
10
  lastValue[count++] = Value;
11
  count %= INTEGRAL;
12
  iValue += Value/INTEGRAL;
13
  return(iValue);
14
}
Gast #862139
und noch was..
Sorry für die vielen Posts, aber so früh am morgen, naja, ihr wisst 
schon :P

#define INTEGRAL 3

float integralWert(float Value)
{
  static float  iValue = 0;
  static float lastValue[INTEGRAL];
  static u08 count;

  iValue -= lastValue[count]/INTEGRAL;
  count++;
  count %= INTEGRAL;
  lastValue[count] = Value;

  iValue += Value/INTEGRAL;
  return(iValue);
}
#862190
Ist dein Wert INTEGRAL immer 3 (oder zumindest nicht wesentlich
größer als 3).

Wenn ja, dann würde ich gar nicht lang umtun und das straight
Forward machen
1
#define INTEGRAL 3
2

3
float integralWert(float Value)
4
{
5
  float  iValue = 0;
6
  static float lastValue[INTEGRAL];
7
  static u08 count = 0;
8

9
  lastValue[count++] = Value;
10
  count %= INTEGRAL;
11
  for( i = 1; i < INTEGRAL; ++i )
12
    iValue += lastValue[i] - lastValue[i-1];
13

14
  return iValue / INTEGRAL;
15
}

Alleine durch das Fortfallen einer Division gewinnst du soviel
Zeit, dass du dir eine Menge anderer Berechnungen erlauben kannst.
Ausserdem hast du den Vorteil, dass sich Rundungsfehler auf die
Art über längere Zeit gesehen nicht aufsummieren.
Gast #862205
Naja, die Schleife kann man sich trotzdem sparen, Fällt natuerlich nur 
für grosse INTEGRAL ins Gewicht.

Aber nochmal zu deinem Problem: Du Willst Mittelwert der Differenzen.
Dann stimmt die Zuweisung
[c]
iValue = (Value - lastValue[(count + INTEGRAL - 2) %INTEGRAL])/INTEGRAL;
[c\]

Und dann müsste dein ursprünglicher Code eigentlich auch richtig sein, 
bis auf die fehlende Initialisierung von count. Ohne Initialisierung 
kann ja sein dass count irgendeinen Wert hat der ausserhalb der Array 
Grenzen liegt und somit dein erster value sonstwo im Speicher landet und 
natuerlich für die folgende Mittelung nicht zur Verfügung steht.
Ausserdem liefert deine Funktion erst nach 3maligem Aufruf sinnvolle 
Werte, davor ist das Array ja noch nicht komplett mit deinen Werten 
gefüllt.
Gast #862353
Hier ein Ansatz µC mit wenig Resourcen , also ohne float nur unsigned 
char und unsigned short:

Allg. Ansatz : Wert1+Wert2+Wert3+Wert3 / 4 = MW über 3 Werte

Hier braucht nur geschoben zu werden "<<1" und ">>2"

Auch wenn Wert3 nun die doppelte Gewichtung besitzt, sollte dies
womöglich für die Anwendung auch egal sein.

Nach dem Teilen ">>2" darf natürlich das Runden der Nachkommastellen
nicht vergessen werden.
#862369
gast wrote:
> Hier ein Ansatz µC mit wenig Resourcen , also ohne float nur unsigned
> char und unsigned short:
>
> Allg. Ansatz : Wert1+Wert2+Wert3+Wert3 / 4 = MW über 3 Werte
>
> Hier braucht nur geschoben zu werden "<<1" und ">>2"
>
> Auch wenn Wert3 nun die doppelte Gewichtung besitzt, sollte dies
> womöglich für die Anwendung auch egal sein.
>
> Nach dem Teilen ">>2" darf natürlich das Runden der Nachkommastellen
> nicht vergessen werden.

ggf kann man auch statt Wert3 den alten Mittelwert nehmen.
Oder man nimmt 16 Werte, also 5 mal den ersten plus 5 mal den 2. plus 5 
mal den dritten und ein alten Mittelwert o. Ä.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 18 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.