Univerzális program RAM használathoz

Az utóbbi időben rákényszerültem külső memória használatára. Ennek kapcsán írtam egy olyan univerzális tároló függvényt, amivel különböző típusú adatokat lehet tárolni. Nem pusztán tárolja az adatokat, átlagol, minimum maximum értéket képez stb. Csak dobálom be az adatokat, és az jön ki, amire kíváncsi vagyok. Még egy érdekessége van ennek a programnak. A fiam elmagyarázta, hogyan lehet úgy használni egy függvényt, hogy meghíváskor a paraméterek száma különböző lehet, és ettől függően mást is csinál. A függvényt multimemo-nak neveztem el. 73 különböző adatot tud tárolni egy 512 byte-os ram-ban. Mind a 73 tároló cellája (én neveztem el így) különböző módon viselkedik, beállítható módon automatikusan képzi a bedobált adatoknak a minimumát, maximumát, átlagát, összegét, vagy csak simán az adatot is képes tárolni. Egy cella egyféle módon állítható be, ez gondolom egyértelmű. Meghívása nagyon kényelmes, így néznek a ki a különböző esetek:

  • multimemo(cím,tipus)  – létrehoz egy megadott típusú memória cellát (setup és reset)
  • multimemo(cím,adat)  – beír egy adatot a cím-el megadott cellába (write)
  • multimemo(cím) – kiolvas a cimről egy adatot (read)

Miközben írtam a programot megtanultam használni az „enum” felsorolás típusú változók használatát is. Sokat segített a program megírásában és áttekinthetőségében, nem kell kódokat megjegyezni, kevésbé fordult elő, hogy összekevertem azokat a bizonyos kódokat.

A multimemo használat igen egyszerű! Meghívjuk a függvényt a cím és a típus megadásával. Ekkor létrejön a tároló cella, megjegyzi a saját típusát és alaphelyzetbe áll. Az alaphelyzet nem feltétlenül nulla tartalmat jelent, mert pl. a minimum tároló cella esetében a long típus lehetséges legnagyobb értékét kell megadni, hiszen ez a cella csak akkor tárolja a megadott tartalmat, ha az kisebb mint az éppen tárolt érték. Úgy írtam meg a függvényt, hogy ebben az alap állapotban 0-át ad vissza, de ha egyetlen értéket is megadsz, már rögtön az lesz a minimum. Az átlagoló cellánál az átlag képzéséhez a beírás számlálót is törölni kell alaphelyzetbe állításkor.
Ezt követően, már csak írogatni kell az adatokat. Ha meghívod a függvényt két paraméterrel, a címmel és az adattal, akkor történik aminek történnie kell. Itt egy kicsi összefoglaló az egyes típusok működéséről:

  • MIN típusú cella: A tároló cella a beadott adatok közül mindig csak azt tárolja, ami kisebb az aktuálisan tárolt értéknél. Kezdő értéke 2.147.483.647, de a visszaadott érték ekkor 0. Ha bármilyen adatot bele írunk, akkor már azt fogja visszaadni (vagy ha az lesz kisebb akkor azt). A 2.147.483.647 értékre mindig 0-at ad vissza, így a tárolható értéktartomány -2.147.483.648-tól 2.147.483.646-ig!
  • MAX típusú cella: A tároló cella a beadott adatok közül mindig csak azt tárolja, ami nagyobb az aktuálisan tárolt értéktől. Kezdő értéke -2.147.483.648, de a visszaadott érték ekkor 0. Ha bármilyen adatot bele írunk, akkor már azt fogja visszaadni (vagy ha az lesz nagyobb akkor azt). A ‑2.147.483.648 értékre mindig 0-at ad vissza, így a tárolható értéktartomány -2.147.483.647-tól 2.147.483.647-ig!
  • SUM típusú cella: A tároló cella a beadott adatot hozzáadja az aktuális értékhez, így mindig az adatok összegét tudjuk. Kezdő érték 0.
  • AVG típusú cella: A tároló cella átlag érték tárolásra lesz használva. Ha beleírunk egy értéket, akkor azt hozzáadja az előzőleg tárolt értékhez, de növeli a beírások számlálóját is. Ha lekérdezzük majd a cella tartalmát, a tárolt szumma érték és a beírás számláló hányadosát (azaz az átlagot) adja vissza. Beírást követően azonnal visszaadja az új átlag értéket. Csak egész értékeket lehet megadni, tehát ha tizedes értékekkel akarunk számolni a 10, 100 stb. szorosát adjuk meg, és kiolvasáskor ugyanannyival osztanunk kell (float-ra alakítva az eredményt). A hányados képzéskor egészre kerekít vagyis pl. 32,666-ra 32-őt ad vissza és nem 33-at, ami kerekítéssel helyes lenne. Erre esetleg érdemes figyelni. Ezért pontosabb eredményt kapunk, ha tizedesek számában többet használunk mint amit a pontosság megkövetel. Tehát egy tizedes pontosság esetén 100-al szorozzunk tároláskor, és 100-al osszunk kiolvasáskor.
  • STO típusú cella: A beírt adat tárolásra kerül. Nem csinálunk vele semmit, csak tároljuk és kiolvasáskor visszaadjuk. Egy új adat beírásakor a régi felülíródik.

Írás után a függvény visszaadja a tároló cella új tartalmát. Ez ugyanaz, mintha kiolvasnánk a benne tárolt értéket.

Írtam egy demó programot a működés bemutatására. A setup részben csak néhány egyszerű művelettel mutatom be a működést. A loop-ban már véletlen szám generálással próbálkoztam. A véletlen szám generálás tulajdonságairól is szereztem tapasztalatokat, de ezzel majd a végén még foglalkozok egy kicsit.

Íme a forráskód:

#include <Wire.h>

//Az i2c címet az A2 és A1 kivezetések állapota határozza meg
//Például, ha A2 = VCC és A1 = GND, írjunk: FRAM fram (0b10);
byte A0A1=0b00;
byte _i2cAddress= (0b101000 | A0A1)<<1;
//_i2cAddress= (0b101000 | Address)<<1;
//byte _i2cAddress= 0b1010000;
byte Page=0;
String anev;
enum cella_tipus { MIN, MAX, SUM, AVG, STO };
long szam;

void setup() {
  Wire.begin();  
  Serial.begin(9600);
  Serial.println("reset...");
  multimemo(0,MIN);  // A 0. fram cella minimum érték tárolásra lesz használva. Kezdő értéke 2.147.483.647,
                     // de a visszaadott érték ekkor 0. Ha bármilyen adatot bele írunk, akkor már azt fogja
                     // visszaadni (vagy ha az lesz kisebb akkor azt). A 2.147.483.647 értékre mindig 0-at ad vissza
                     // Az értéktartomány -2.147.483.648-tól 2.147.483.646-ig!
  multimemo(1,MAX);  // A 1. fram cella macimum érték tárolásra lesz használva. Kezdő értéke -2.147.483.648,
                     // de a visszaadott érték ekkor 0. Ha bármilyen adatot bele írunk, akkor már azt fogja
                     // visszadni (vagy ha az lesz nagyobb akkor azt). A -2.147.483.648 értékre mindig 0-at ad vissza
                     // Az értéktartomány -2.147.483.647-tól 2.147.483.647-ig!
  multimemo(2,SUM);  // A 2. fram cella szumma érték tárolásra lesz használva. Ha beleírunk egy értéket
                     // az mindíg hozzáadódik az addig tárolt adathoz, és az lesz a következő tárolt érték. 
                     // Kezdő tárolt adat 0.
  multimemo(3,AVG);  // A 3. fram cella átlag érték tárolásra lesz használva. Ha beleírunk egy értéket, akkor azt hozzáadja
                     // az előzőleg tárolt értékhez, de növeli a beírások számlálóját is. Ha lekérdezzük majd a cella
                     // tartalmát, a tárolt szumma éréték és a beírás számláló hányadosát (azaz az átlagot) adja vissza.
                     // csak egész értékeket lehet megadni, tehát ha tizedes értékekkel akarunk számolni a 10, 100 stb.
                     // szorosát adjuk meg, és kiolvasáskor ugyanannyival oszzunk (float-ra alakítva az eredméynt).
                     // A hányados képzéskor egészre kerekít vagyis pl. 32,666-ra 32-őt ad vissza és nem 33-at, ami 
                     // kerekítéssel helyes lenne. Erre esetleg érdemes figyelni. Érdemes tizedessek számában többet
                     // használni mint amit a pontosság megkövetel, tehát egy tizedes pontosság esetén 100-al szorozzunk tároláskor,
                     // és 100-al osszunk kiolvasáskor.
  multimemo(4,STO);  //A 4. fram cella tárolásra kerül. Nem csinálunk vele semmit, csak tároljuk.

  Serial.println("tárolás...");
  // Sokféle értéket írunk a cellákba, hogy láthassuk a működést. A visszadott érték a beírást
  // követő cella tartalmat adja vissza. Ha írni akarunk egy tároló cellába, akkor két paramétert
  // adunk meg, a cella címét és a tárolandó adot. Az adatot nem tároljuk, hanem értékeljük és tárolunk 
  // attól függően, hogy milyen típusú a tároló cellánk. A cella típusát reseteléskor (alap beállításkor) 
  // adjuk meg. Lásd előbbi két paraméteres meghívás, amikor a második paraméter string.
  Serial.print("MIN (10):");Serial.println(multimemo(0,10));
  Serial.print("MIN  (5):");Serial.println(multimemo(0,5));
  Serial.print("MAX (20):");Serial.println(multimemo(1,20));
  Serial.print("MAX (15):");Serial.println(multimemo(1,15));
  Serial.print("SUM (30):");Serial.println(multimemo(2,30));
  Serial.print("SUM (20):");Serial.println(multimemo(2,20));
  Serial.print("AVG (42):");Serial.println(multimemo(3,42));
  Serial.print("AVG (37):");Serial.println(multimemo(3,37));
  Serial.print("AVG (19):");Serial.println(multimemo(3,19));
  Serial.print("STO (50):");Serial.println(multimemo(4,50));
  
  Serial.println("Kiolvasott cella tartalmak:");
  Serial.print("MIN:");Serial.println(multimemo(0));
  Serial.print("MAX:");Serial.println(multimemo(1));
  Serial.print("SUM:");Serial.println(multimemo(2));
  Serial.print("AVG:");Serial.println(multimemo(3));
  Serial.print("STO:");Serial.println(multimemo(4));

  //a loop-ban található teszt programban tárolt adatokhoz a tároló cellák létrehozása
  multimemo(5,MIN);  // A 5. fram cella minimum érték tárolásra lesz használva. Ebben tároljuk a generált számok között előforduló minimális értéket
  multimemo(6,MAX);  // A 6. fram cella macimum érték tárolásra lesz használva. Ebben tároljuk a generált számokban előforduló maximális értéket
  multimemo(7,SUM);  // A 7. fram cella szumma érték tárolásra lesz használva. Ehhez adjuk hozzá a generált számot
  multimemo(8,SUM);  // A 8. fram cella szumma érték tárolásra lesz használva. Ebben számoljuk a generált számok mennyiségét
  multimemo(9,AVG);  // A 9. fram cella átlag érték tárolásra lesz használva. Ebben tároljuk a generált számok átlagát
  
}


void loop() {
  szam=random(-10000,20000);
  Serial.print("Generalt szam:");
  Serial.print(szam);
  Serial.print("  MIN:");Serial.print(multimemo(5,szam));
  Serial.print("  MAX:");Serial.print(multimemo(6,szam));
  Serial.print("  SUM:");Serial.print(multimemo(7,szam));
  Serial.print("  AVG");Serial.print(multimemo(9,szam));
  Serial.print("  Db:");Serial.print(multimemo(8,1));
  Serial.print("  szamitott atlag:");Serial.print(multimemo(7)/multimemo(8));
  Serial.println();
  delay(100);
}


long multimemo(byte cim) {
/***************************************************************************************************************
 * Ez a multimemo függvény akkor hívódik meg, ha csak egyetlen paramétert adtunk meg a függvény                *
 * meghívásakor (csak olvasni akarunk a tároló cellából)                                                       *
 * A három paraméteres multimemo függvényt hívja meg, de default értékkel tölti fel a maradék két paramétert   *
 * A megadott tároló cella címről adtot fogunk olvasni.                                                        *
 ***************************************************************************************************************/
  long adat=0;
  bool iras=0;
  return(multimemo(cim,adat,iras));
}


long multimemo(byte cim, long adat) {
/***************************************************************************************************************
 * Ez a multimemo függvény akkor hívódik meg, ha két paramétert adunk meg, a cella címét és a beírandó         *
 * adatot, vagyis írni akarunk a cellába. A tároló cella formázását és alaphelyzetbe állítását végző           *
 * két paraméteres multimemo függvénytől az különbözteti meg, hogy ennek második paramétere long típusú.       *
 * A három paraméteres multimemo függvényt hívja meg, de a harmadik paramétert (iras vagy olvasás) default     *
 * értékkel tölti fel (iras=1, azaz írunk). A megadott tároló cella címébe fogjuk az adtot beírni.             *
 ***************************************************************************************************************/
  bool iras=1;
  return(multimemo(cim,adat,iras));
}



long multimemo(byte cim, long adat, bool iras) {
/*****************************************************************************************************************************************************************
 * Ez a multimemo függvény akkor hívódik meg, ha három paraméterrel hívjuk. Ez végzi a tárolandó adat feldolgozását, tárolását, és visszaadja az eredményt       *  
 * visszatérő értékként. A tároló cella típusát az első tárolt byte adja meg, ezt az a multimemo függvény írja, melynek két paramétere van, és a második         *
 * cella_tipus (enum-al definiált felsorolás) típusú adatot vár.                                                                                                 *
 * A függvény bemenő paraméterei:                                                                                                                                *
 *    cim: 0-73 memória cella, egy cella 7 byte,                                                                                                                 *
 *    adat: long típusú 4 byte-os adat, amit beírunk a kijelölt memória cellába                                                                                  *
 *    iras: ez mondja meg, hogy írunk vagy olvasunk a tároló cellából. 0-olvasunk, 1-írunk                                                                       *
 * A tároló cella szerkezete:                                                                                                                                    *
 *    0. byte típus: 0=minimum cella, 1=maximum cella, 2=summa cella, 3=átlag cella, 4=tároló cella                                                              *
 *    1-4. byte adat long adattípus, ez a tényleges tárolt long adat 4 byte-on                                                                                   *
 *    5-6. byte átlag esetén az összegzett adatok száma int adattípusú Csak az átlagoló tároló cella használja, ebben számolja az írások számát.                 *
 *****************************************************************************************************************************************************************/
  int xcim=cim*7;
  byte page=0;
  byte adat0;
  byte adat1;
  byte adat2;
  byte adat3;
  if (xcim<256) {page=0;} else {page=1;xcim=xcim-256;}
  Wire.beginTransmission(_i2cAddress | (page&1));
  Wire.write(xcim);
  Wire.endTransmission(); 
  Wire.requestFrom(_i2cAddress | (page&1),7);
  byte xtipus=Wire.read();  //elkérjük az első byte-ot, ami a tárolt dat típusát adja meg
  long xadat=long(Wire.read()) | long(Wire.read())<<8 | long(Wire.read())<<16 | long(Wire.read())<<24 ; //elkérjük és betöltjük az adat aktuális értékét
  int xdb=int(Wire.read()) | int(Wire.read())<<8;  //elkérjük és betöltjük az adatok számát
  
  if (iras==0 and xtipus!=3) {return(xadat);}  //ha olvasás és nem átlagot kértünkvolt a művelet, akkor visszadjuk a kiolvasott long értéket
  if (iras==0 and xtipus==3) {if (xdb>0) {return((long)(xadat/xdb));} else {return(0);}}  //ha olvasás és átlagot kértünk, akkor osztani is kell, de csak ha xdb nem 0
  
  if (xtipus==0 and iras==1){ //ha írás ésminimum cella
      if (xadat>adat) { //csak akkor írjuk be az új adatot, ha az eddig tárolt adatnál kissebb
        multimemo_adatiras(page,xcim,adat); //visszaírjuk az új adatot a tároló cellába
        return(adat);
      }
      else {return(xadat);} //visszadjuk a cellában tárolt minimum értéket
    }  
      
  if (xtipus==1 and iras==1){  //ha írás és maximum cella
      if (xadat<adat) {  //csak akkor írjuk be az új adatot, ha az eddig tárolt adatnál nagyobb
         multimemo_adatiras(page,xcim,adat); //visszaírjuk az új adatot a tároló cellába
        return(adat);
      }
      else {return(xadat);} //visszadjuk a cellában tárolt maximum értéket
    }  
      
  if (xtipus==2 and iras==1){  //ha írás és summa cella
    adat=xadat+adat;  //összeadjuk az új adatot ez eddig beírt adatok (tárolt) összegével
    multimemo_adatiras(page,xcim,adat);  //visszaírjuk az új adatot a tároló cellába
    return(adat); //visszadjuk az új cella értéket
  } 

  if (xtipus==3 and iras==1){  //ha írás és átlag cella
    adat=xadat+adat;  //összeadjuk az új adatot ez eddig beírt adatok (tárolt) összegével
    xdb=xdb+1; //növeljük a beírások számát 1-el
    Wire.beginTransmission(_i2cAddress | (page&1));Wire.write(xcim+1); //a cella első byte-ját már nem kell írni, azt beállított a cella reset, azért cim+1-től írunk
    Wire.write(adat & 0xFF);Wire.write((adat>>8) & 0xFF);Wire.write((adat>>16) & 0xFF);Wire.write((adat>>24) & 0xFF); //beírjuk az új összegzett adatot
    Wire.write(xdb & 0xFF);Wire.write((xdb>>8) & 0xFF);  //beírjuk az írások számát
    Wire.endTransmission(); 
    return((long)(adat/xdb));  //visszadjuk az új átlag értéket
  } 

  if (xtipus==4 and iras==1){  //ha írás és sima tároló cella
    multimemo_adatiras(page,xcim,adat);
    return(adat);
  } 

}

void multimemo_adatiras(byte page, byte xcim, long adat) {
// az átlag cella kivételével mindet ugyanúgy kell beírni, ezért a konkrét írás ebben a közösen használt függvényben lett megvalósítva
  Wire.beginTransmission(_i2cAddress | (page&1));Wire.write(xcim+1); //a cella első byte-ját már nem kell írni, azt beállított a cella reset, azért cim+1-től írunk
  Wire.write(adat & 0xFF);Wire.write((adat>>8) & 0xFF);Wire.write((adat>>16) & 0xFF);Wire.write((adat>>24) & 0xFF);
  Wire.endTransmission(); 
}

long multimemo(byte cim, cella_tipus tipus) {
/*******************************************************************************************************************************************************************  
 * Ez a multimemó függvény akkor hívódik meg, ha két paraméterrel hívjuk, és a második cella_tipus típusú változó, amit enum-al hoztunk létre a program elején.    *
 * A függvény elvégzi egy cella típusának beállítását (a cella első byte-ja), és alaphelyzetbe állítja a tárolt adatokat.                                          *
 * Bemenő paraméterek:                                                                                                                                             *
 *    cim: 0-73 db memória cella, egy cella 7 byte,                                                                                                                *
 *    típus: felsorolás típusú (enum) paraméter, ami meghatározza a cella tárolási módját. Lehetséges értékei 0-4 között.                                          *
 * Típus által képzett cella típusok, és azok tárolási módja, az elvégzett műveletek leírása:                                                                      *
 *  MIN: Az íráskor megkapott adatot csak akkor tárolja, ha az kissebb mint az éppen tárolt adat. Mielőtt elkezdjük a minimumot gyüjteni, be kell írni             *
 *       a lehető legnagyobb long értéket, különben nem biztos, hogy megjegyzi a legelső értéket. A számláló cellarészt nem használja.                             *
 *  MAX: Az íráskor megkapott adatot csak akkor tárolja, ha az nagyobb mint az éppen tárolt adat. Mielőtt elkezdjük a maximumott gyüjteni, be kell írni            *
 *       a lehető legkissebb long értéket, különben nem biztos, hogy megjegyzi a legelső értéket.                                                                  *
 *  SUM: Képzi a beírt adatok összegét. Alapértelmezetten a tartalma 0.                                                                                            *
 *  AVG: képzi a beírt adatok átlagát. Minden beít értéket szummáz az adat mezőben, számolja a beírások számát, és kiolvasáskor osztja az adatot a beírás számmal  *
 *       Alpértelmezetten az adat és a számláló is 0.                                                                                                              *
 *  STO: csak úgy simán tárolja az adatot, nem csinál vele semmit, ha volt bent előtte adat, azt felülírja. Alepértelmezett tartalma 0.                            *
 *******************************************************************************************************************************************************************/
  int xcim=cim*7;
  byte page;
  if (xcim<256) {page=0;} else {page=1;xcim=xcim-256;}
  Wire.beginTransmission(_i2cAddress | (page&1));
  Wire.write(xcim);
  if (tipus==MIN){
      // 2147483647 kezdő értéket írunk a tároló cellába, mert nincs nagyobb szám long esetén, így csak ennél kisebbek jöhetnek.
      Wire.write(0);Wire.write((long)2147483647 & 0xFF);Wire.write(((long)2147483647>>8) & 0xFF);Wire.write(((long)2147483647>>16) & 0xFF);Wire.write(((long)2147483647>>24) & 0xFF);
      Wire.write(0);Wire.write(0);
      Wire.endTransmission(); 
      return(0);
    }    
  if (tipus==MAX){
      // -2147483648 kezdő értéket írunk a tároló cellába, mert nincs kisebb szám long esetén, így csak ennél kisebbek jöhetnek.
      Wire.write(1);Wire.write((long)-2147483648 & 0xFF);Wire.write(((long)-2147483648>>8) & 0xFF);Wire.write(((long)-2147483648>>16) & 0xFF);Wire.write(((long)-2147483648>>24) & 0xFF);
      Wire.write(0);Wire.write(0);
      Wire.endTransmission(); 
      return(0);
    }    
  if (tipus==SUM or tipus==AVG or tipus==STO) {
      //össegző mező esetén csak simán törölni kell mindent
      Wire.write(tipus);Wire.write(0);Wire.write(0);Wire.write(0);Wire.write(0);
      Wire.write(0);Wire.write(0);
      Wire.endTransmission(); 
      return(0);
    }  
    Wire.endTransmission(); 
}

…és a soros port-ra kiírt eredmény első néhány sora:

reset...
tárolás...
MIN (10):10
MIN  (5):5
MAX (20):20
MAX (15):20
SUM (30):30
SUM (20):50
AVG (42):42
AVG (37):39
AVG (19):32
STO (50):50
Kiolvasott cella tartalmak:
MIN:5
MAX:20
SUM:50
AVG:32
STO:50
Generalt szam:6807  MIN:6807  MAX:6807  SUM:6807  AVG6807  Db:1  szamitott atlag:6807
Generalt szam:15249  MIN:6807  MAX:15249  SUM:22056  AVG11028  Db:2  szamitott atlag:11028
Generalt szam:73  MIN:73  MAX:15249  SUM:22129  AVG7376  Db:3  szamitott atlag:7376
Generalt szam:3658  MIN:73  MAX:15249  SUM:25787  AVG6446  Db:4  szamitott atlag:6446
Generalt szam:18930  MIN:73  MAX:18930  SUM:44717  AVG8943  Db:5  szamitott atlag:8943 

Érdekes eredményre vezetett ez a program. -10.000 és +20.000 közötti véletlen számot generáltam, és a multimemo segítségével tároltam a generált számok minimumát, maximumát, összegét, átlagát és ellenőrzési céllal minden generáláskor növeltem az egyik cella értékét. Az a nem túlságosan meglepő eredmény született, hogy véletlen generátor nem teljesen ideális. Ahogy növeltem a generált számok mennyiségét, az átlagnak 5.000-re kellett volna adódnia. Azonban nem így történt, kis mértékben mindig eltért tőle. Nem is olyan kicsi mértékben. Mivel kiírtam a generált db számot is, látható, hogy 20.000 véletlen szám átlaga az ideális 5000 helyett 5038.Ez szerintem elég durva eltérés. Másik érdekes megfigyelés lehet, hogy a maximum értéke 20000 generált szám esetében is csak 19992. Ez még nem rossz eredmény, nem számoltam ki a valószínűségét, hogy ennyi generált szám esetén mi a várható maximum. Pár sort ki is emeltem a program output-ból, hogy látható legyen miről beszélek:

Generalt szam:6807  MIN:6807  MAX:6807  SUM:6807  AVG6807  Db:1  szamitott atlag:6807
Generalt szam:15249  MIN:6807  MAX:15249  SUM:22056  AVG11028  Db:2  szamitott atlag:11028
Generalt szam:73  MIN:73  MAX:15249  SUM:22129  AVG7376  Db:3  szamitott atlag:7376
Generalt szam:3658  MIN:73  MAX:15249  SUM:25787  AVG6446  Db:4  szamitott atlag:6446

Generalt szam:-2793  MIN:-10000  MAX:19992  SUM:24894628  AVG4979  Db:4999  szamitott atlag:4979
Generalt szam:-4573  MIN:-10000  MAX:19992  SUM:24890055  AVG4978  Db:5000  szamitott atlag:4978
Generalt szam:5258  MIN:-10000  MAX:19992  SUM:24895313  AVG4978  Db:5001  szamitott atlag:4978
Generalt szam:-8634  MIN:-10000  MAX:19992  SUM:24886679  AVG4975  Db:5002  szamitott atlag:4975 

Generalt szam:16085  MIN:-10000  MAX:19992  SUM:49578804  AVG4958  Db:9998  szamitott atlag:4958
Generalt szam:16315  MIN:-10000  MAX:19992  SUM:49595119  AVG4960  Db:9999  szamitott atlag:4960
Generalt szam:-1935  MIN:-10000  MAX:19992  SUM:49593184  AVG4959  Db:10000  szamitott atlag:4959
Generalt szam:13406  MIN:-10000  MAX:19992  SUM:49606590  AVG4960  Db:10001  szamitott atlag:4960

Generalt szam:-8997  MIN:-10000  MAX:19992  SUM:75662129  AVG5044  Db:14998  szamitott atlag:5044
Generalt szam:17916  MIN:-10000  MAX:19992  SUM:75680045  AVG5045  Db:14999  szamitott atlag:5045
Generalt szam:7885  MIN:-10000  MAX:19992  SUM:75687930  AVG5045  Db:15000  szamitott atlag:5045
Generalt szam:15235  MIN:-10000  MAX:19992  SUM:75703165  AVG5046  Db:15001  szamitott atlag:5046 

Generalt szam:-8163  MIN:-10000  MAX:19992  SUM:100768475  AVG5038  Db:19998  szamitott atlag:5038
Generalt szam:-2033  MIN:-10000  MAX:19992  SUM:100766442  AVG5038  Db:19999  szamitott atlag:5038
Generalt szam:10914  MIN:-10000  MAX:19992  SUM:100777356  AVG5038  Db:20000  szamitott atlag:5038
Generalt szam:-798  MIN:-10000  MAX:19992  SUM:100776558  AVG5038  Db:20001  szamitott atlag:5038 

Mennyire volt hasznos amit olvastál?

Kattints egy csillagra az értékeléshez!

Sajnálom, hogy amit olvastál nem volt hasznos számodra!

Szeretném ha elégedett lennél!

Írd le kérlek, hogy mi nem tetszett!?