Suma liczb w języku C

0

Mam następujący problem. Odczytuję z urządzenia pomiarowego wartość co 5 sek, korzystając z gotowej biblioteki w C dostarczonej przez producenta. Są tp liczby typu float. Istotne jest policzenie średniej z 50 pomiarów. W tej chwili po prostu dodaję wartości kolejnych 50 pomiarów i potem dzielę przez 50. No tylko że w tym momencie mam tak naprawdę jeden wynik docelowy pomiaru co 250 sek. A mnie zależy żeby wynik docelowy pomiaru był co 5 sek. Tak więc najstarsza dodana wartość powinna być odjęta a dodana najnowsza wartość. Ma ktoś z Kolegów pomysł na parę linijek w C które by załatwiły ten problem? Proszę zauważyć że nie interesuje mnie kolejność zapisanych pomiarów ale suma ostatnich 50, zmieniana co 5 sek po nadejściu nowej wartości.

1

Potrzebujesz zaimplementować kolejkę / tablicę rotacyjną na 50 elementów.
Ostatni element usuwać.
Z tej tablicy liczyć sobie średnią.

0

Fajnie, tylko że u mnie z programowaniem kruchawo, bo to ni mój zawód.

0

Coś w tym stylu co niżej.
Jest to najprostsze rozwiązanie problemu.
Nie jest z pewnością optymalne. Lepiej byłoby mieć wskaźnik na kolejny element do podmiany w tablicy -> unikniemy wtedy przesuwania.
Oczywiście średnią możesz dopiero zacząć liczyć, gdy już będziesz miał pierwsze 50 elementów, czyli po czasie 50 * 5s;

    #include <stdio.h>
    
    #define MAX_ARRAY 50
    int arr[MAX_ARRAY];
   
    void newElement(int element)
    {
    	/* shift elements */
    	for (int i = MAX_ARRAY-i;i>0;i--)
    	{
    		arr[i] = arr[i-1];
    	}
    	/* new element */
    	arr[0] = element;
    }
    
    double avg()
    {
    	double tmp = 0.0f;
    	for (int i = 0 ;i<MAX_ARRAY;i++)
    	{
    		tmp += arr[i];
    	}
    	return tmp/MAX_ARRAY;
    }
    
    int main()
    {
    	/* wait for data */
    	for (int i = 0 ;i < MAX_ARRAY;i++)
    	{
    		arr[i] = i;
    	}
    	printf("avg %f\n",avg());
    	newElement(69);
    	printf("avg %f\n",avg());
    	newElement(11);
    	printf("avg %f\n",avg());
    	for (int i = 0;i<MAX_ARRAY;i++)
    	{
    		printf("arr[%d] = %d\n",i, arr[i]);
    	}
    }
0

Jasne. Dzięki Kolego, popróbuję !

3

Ten kod powyżej to właśnie przykład jak nie należy tego robić.
Hasła do wyszukania:

  • "bufor cykliczny"
  • "bufor kołowy"

Wyniki:
http://www.embeddeddev.pl/bufor-kolowy-1-zasada-dzialania/
https://darvark.wordpress.com/2014/12/07/ringbuffer-prosty-bufor-cykliczny/

0

Zrobiłem to bardzo prymitywnie ale skutecznie. Zrzucam wyniki pomiarów do ramdisku, każdy wynik pomiaru jest w osobnej linii. Używam 200MB ramdisk gdzie wykonuję właściwie wszystkie operacje dyskowe bo jest to Malinka a więc inaczej "zarżnął" bym kartę SD, (szczególnie plikami tymczasowymi SQL Lite).. A następnie wywołuję za pomocą instrukcji "system" funkcje bash "tail -50". Teraz pytanie jak po otworzeniu pliku w C, zsumować wszystkie liczby w kolejnych liniach. Plik przecież jest tekstowy. W bash to potrafię ale w C - nie. Jakaś pomoc?

0
vpiotr napisał(a):

Ten kod powyżej to właśnie przykład jak nie należy tego robić.
Hasła do wyszukania:

  • "bufor cykliczny"
  • "bufor kołowy"

Wyniki:
http://www.embeddeddev.pl/bufor-kolowy-1-zasada-dzialania/
https://darvark.wordpress.com/2014/12/07/ringbuffer-prosty-bufor-cykliczny/

Bufor cykliczny to pierwszy rok informatyki, względnie 3ci semestr. Tego się nie zapomina jak jazdy na rowerze.

0

Pewnie tak. Ja ukończyłem studia z automatyki w 1986 roku. Trochę stareńki więc jestem. A na 3 semestrze to miałem "Teorię obwodów i sygnałów" i "Analizę matematyczną". A programowałem wtedy w językach Algol, Pascal, Plan i Fortran. Tak nota bene WSZYSTKIE biblioteki matemetyczne C są napisane w Fortranie. No prawie wszystkie.
Ale to zastosowane przeze mnie rozwiązanie ma jeszcze jedną istotną zaletę z punktu widzenia urządzenia które robię. Otóż przechowywanie danych na ramdisku pozwala na łatwe synchronizowanie/przekazywanie danych do centralnego serwera i tam opracowywanie ich do formy docelowej. Tak więc - w moim konkretnym przypadku - bufor kołowy byłby właściwie przeszkodą.

1

To rozwiązanie które zrobiłeś jest rodem z mainframe.
OK, jeśli działa to nie ma co drążyć, miej tylko świadomość że są inne, lepsze rozwiązania.

0

Tak kończąc temat - faktycznie. Rodem z mainframe. Bo uważam że SNA (tak był kiedyś taki protokół sieciowy) był the best. Cała reszta w tym wszystkie dodatki do TCP/IP czy UDP to tylko próba dorównaiania temu ideałowi. Ale cóż. Stareńki już jestem i może się mylę.
Życzę zdrowia Koledze i w sumie bardzo dziękuję. Bo dzięki Tobie wpadłem na pomysł który mi teraz działa idealnie.

1 użytkowników online, w tym zalogowanych: 0, gości: 1