Textdatei auslesen und verarbeiten [geloest]
-
Hallöchen,
ich habe eine txt-Datei bekommen, in welcher viele Werte wie 100.002312, 99.784123, 101.525040,...
Nun soll ich diese Werte auslesen, in einem Vector speichern und anschließend verarbeiten (Mittelwert und Standardabweichung berechnen).
Mein Code bisher lautet wie folgt:#include<iostream> #include<fstream> #include<string> #include<vector> int main() { char ch; std::fstream Datei; std::string Dateiname; std::cin >> Dateiname; Datei.open(Dateiname.c_str(), std::ios::binary|std::ios::in); long Anzahl = 0; double L[50000]; // Anzahl Werte while (Datei.get(ch)) { if (ch=='\n') { Anzahl++; } } Datei.clear(); Datei.seekg(std::ios_base::beg); // vector L mit Werten fuellen while (Datei.get(ch)) { for (int i = 0; i <= Anzahl; i++) { L[i] = ch; } } // MIttelwert double Summe = 0; for (int i = 0; i <= Anzahl; i++) { Summe += L[i]; } double MW = 0; MW = Summe / Anzahl; // Standardabweichung double V[50000]; // vector V mit Werten SA fuellen for (int i = 0; i <= Anzahl; i++) { V[i] = (L[i]-MW); } double SA = 0; for (int i = 0; i <= Anzahl; i++) { SA += V[i]; } SA /= Anzahl; std::cout << "\n\nMittelwert: " << MW << "\n\nStandardabweichung: " << SA; std::cin.get(); return 0; }
Es kommt aber leider zu keiner Ausgabe mehr.
Bitte um Hilfe und Danke im Voraus
MfG
-
Falls die Datei wirklich nur die Zahlen von Whitespaces getrennt beinhaltet:
ifstream datei("DeinDateiName.txt"); // double zahl; while(datei >> zahl) { cout << zahl << '\n'; //mach irgendwas mit der eingelesenen Zahl }
-
1. Wie wäre es als Anfang damit, tatsächlich einen Vector zu benutzen?
2. Warum liest du Zeichen, wenn du Zahlen lesen möchtest?
3. So etwas kann man wunderbar mit einem Debugger nachvollziehen. Lerne damit umzugehen, der Debugger gilt als wichtigstes Werkzeug des Programmierers. Gehe als Übung schrittweise durch das Programm. Wenn das Programm an einer Stelle anders verzweigt, als von dir erwartet, dann schau dir den Zustand der Variablen an und verfolge zurück, wieso deren Werte anders sind als erwartet.Ein Ansatz zum Einlesen:
vector <double> data; for (double value; file >> value; data.push_back(value)); // Nun Daten verarbeiten
Und eine Komplettlösung, die unnötigen Kram über Bord schmeißt, somit jedoch nicht mehr die Aufgabenstellung im strengen Sinne erfüllt:
#include <iostream> #include <cmath> int main() { unsigned int N = 0; double mean = 0; double m2 = 0; for(double value ; std::cin >> value; ) { ++N; double delta = value - mean; mean += delta / N; m2 += delta*(value - mean); } std::cout << mean << '\t' << std::sqrt(m2 / (N - 1)) << '\n'; }
Wie du siehst, braucht man die Daten gar nicht zwischenzuspeichern, wenn man genau über das Problem nachdenkt. Oder besser noch, wenn man bei klugen Leuten abschreibt, die über das Problem nachgedacht haben. Dieser spezielle Algorithmus stammt von Numeriklegende Donald Knuth.
-
SeppJ schrieb:
1. Wie wäre es als Anfang damit, tatsächlich einen Vector zu benutzen?
Ein Ansatz zum Einlesen:
vector <double> data; for (double value; file >> value; data.push_back(value)); // Nun Daten verarbeiten
versucht, hat nicht funktioniert
( vector<double> L[50000] )SeppJ schrieb:
2. Warum liest du Zeichen, wenn du Zahlen lesen möchtest?
mit double/float hat es nicht funktioniert, ebenso wenig int etc, habe mir überlegt char zu verwenden, da ich es als string zwischengespeichert habe.
SeppJ schrieb:
3. So etwas kann man wunderbar mit einem Debugger nachvollziehen. Lerne damit umzugehen, der Debugger gilt als wichtigstes Werkzeug des Programmierers.
Stimmt, muss ich mich erstmal dran gewöhnen, vergesse den immer
-
xStrykex schrieb:
versucht, hat nicht funktioniert
( vector<double> L[50000] )*was genau* hast du da versucht? Ich hab so den Verdacht, du hast absolut keine Ahnung, wie man mit einem std::vector umgeht.
-
xStrykex schrieb:
versucht, hat nicht funktioniert
( vector<double> L[50000] )Das ist ein Array von Vectoren. Klar funktioniert das nicht. Guck dir nochmal an, wie man vector richtig benutzt. Und vergiss den ganzen Arrayunfug. Brauchst du in C++ vorerst nicht. Wo hast du das überhaupt her?
Außerdem solltest du Codes die dir vorgegeben werden, auch genau so benutzen, anstatt sie zu verändern und dann zu behaupten, sie würden nicht funktionieren.
mit double/float hat es nicht funktioniert, ebenso wenig int etc, habe mir überlegt char zu verwenden, da ich es als string zwischengespeichert habe.
Kannst du auch mal mehr als Fehlerbeschreibung geben, als "funktioniert nicht"? Wie soll man dir helfen, wenn wir nicht wissen, was du gemacht hast, noch wenn du selber nicht versucht hast, den Fehler zu finden? Vielleicht ist der Grund ganz ein anderer, wie zum Beispiel das obige Vectorarray. Oder die Datei ist ganz anders aufgebaut als du beschreibst.
Rumraten ist jedenfalls eine denkbar schlechte Methode, um Fehler zu beheben. Wenn es mit double nicht wie gewünscht funktioniert, dann find raus, warum. Probier nicht wild andere Sachen aus, ohne zu wissen, wie es mit denen geht oder warum es mit denen überhaupt gehen sollte. Programmieren ist Logik pur, du musst von jedem einzelnen Zeichen in deinem Programm genau wissen, was es tut und warum du es an der Stelle gesetzt hast.
-
SeppJ schrieb:
xStrykex schrieb:
versucht, hat nicht funktioniert
( vector<double> L[50000] )Das ist ein Array von Vectoren. Klar funktioniert das nicht. Guck dir nochmal an, wie man vector richtig benutzt. Und vergiss den ganzen Arrayunfug. Brauchst du in C++ vorerst nicht. Wo hast du das überhaupt her?
Bücher "Breymann - C++ Programmierer" und "Balzert - Objektmodellierung".
Habe grade nochmal nachgeguckt und in Breymann gefunden, müsste (50000) sein statt [50000]. Verwechselt
Und das (50000) sollte ich besser weglassen, oder?
Wäre dort ein weiterer Unterschied außer, dass (50000) besagt, dass der double-vector 50000 Werte aufnehmen kann?SeppJ schrieb:
Wenn es mit double nicht wie gewünscht funktioniert, dann find raus, warum. Probier nicht wild andere Sachen aus, ohne zu wissen, wie es mit denen geht oder warum es mit denen überhaupt gehen sollte.
Hast du recht, war ein wenig frustriert (nicht meine einzige Baustelle).
Ich bräuchte vllt mal eine Seite, wo alle "Befehle" wie '\t', '\n'(=Zeilenumbruch), '\s',... enthalten sind, werde nicht fündig, da ich nicht weiss, wie man die im Allgemeinen nennt
SeppJ schrieb:
Kannst du auch mal mehr als Fehlerbeschreibung geben, als "funktioniert nicht"?
Das Problem waren die Operatoren in den for-Schleifen, da (meine Vermutung) char in den vector(-array)<double> gespeichert werden sollte
-
xStrykex schrieb:
Wäre dort ein weiterer Unterschied außer, dass (50000) besagt, dass der double-vector 50000 Werte aufnehmen kann?
Nein, es besagt, dass der Vector mit einem Inhalt von 50000 double-Werten gefüllt anfängt (genauer haben diese alle den Wert 0, wenn du es wie hier gezeigt machst). Das ist kein reserve! reserve würde nur die Möglichkeit einräumen, den vector ohne Reallocation auf 50000 Elemente zu vergrößern, ohne die Größe tatsächlich zu verändern. Beides ist hier jedoch fehl am Platz, da du keine Ahnung hast, wie viele Werte kommen werden und du ohnehin keine Angst vor Reallocation haben musst, da du hier keine Iteratoren hast, die ungültig werden könnten.
Ich bräuchte vllt mal eine Seite, wo alle "Befehle" wie '\t', '\n'(=Zeilenumbruch), '\s',... enthalten sind, werde nicht fündig, da ich nicht weiss, wie man die im Allgemeinen nennt
Das sind Escapesequenzen:
http://en.cppreference.com/w/cpp/language/escapeSeppJ schrieb:
Kannst du auch mal mehr als Fehlerbeschreibung geben, als "funktioniert nicht"?
Das Problem waren die Operatoren in den for-Schleifen, da (meine Vermutung) char in den vector(-array)<double> gespeichert werden sollte
char kann implizit in double konvertiert werden. Es sind natürlich die völlig falschen Werte, da du den Wert der einzelnen Zeichen (noch dazu nur das letzte je Zeile) im Zeichensatz speicherst, nicht die Bedeutung der Zeichenketten als Kommazahl abspeicherst. An sich sollte dein Programm aber irgendeine Art von Ausgabe machen, bloß eine total unerwartete.
Apropos unerwartete Ausgabe: Du wirst feststellen, dass deine Berechnung der Standardabweichung ebenfalls falsch ist. Guck dir nochmal an, wie das geht.
-
SeppJ schrieb:
xStrykex schrieb:
Ich bräuchte vllt mal eine Seite, wo alle "Befehle" wie '\t', '\n'(=Zeilenumbruch), '\s',... enthalten sind, werde nicht fündig, da ich nicht weiss, wie man die im Allgemeinen nennt
Das sind Escapesequenzen:
http://en.cppreference.com/w/cpp/language/escapeDanke
SeppJ schrieb:
xStrykex schrieb:
SeppJ schrieb:
Kannst du auch mal mehr als Fehlerbeschreibung geben, als "funktioniert nicht"?
Das Problem waren die Operatoren in den for-Schleifen, da (meine Vermutung) char in den vector(-array)<double> gespeichert werden sollte
char kann implizit in double konvertiert werden.
Quasi mit static_cast?
SeppJ schrieb:
Apropos unerwartete Ausgabe: Du wirst feststellen, dass deine Berechnung der Standardabweichung ebenfalls falsch ist. Guck dir nochmal an, wie das geht.
Stimmt, quadrieren
danke
-
xStrykex schrieb:
Quasi mit static_cast?
Nein, das wäre eine explizite Typumwandlung. Es geht ohne. Machst du wahrscheinlich standig, ohne überhaupt darüber nachzudenken.
char foo = 3; // 3 ist Integer. Nach dieser Zuweisung ist foo == '\x03' (char) double bar = foo; // Nach dieser Zuweisung ist bar == 3.0 (double)
-
SeppJ schrieb:
xStrykex schrieb:
Quasi mit static_cast?
Nein, das wäre eine explizite Typumwandlung. Es geht ohne. Machst du wahrscheinlich standig, ohne überhaupt darüber nachzudenken.
char foo = 3; // 3 ist Integer. Nach dieser Zuweisung ist foo == '\x03' (char) double bar = foo; // Nach dieser Zuweisung ist bar == 3.0 (double)
Ne implizite Typumwandlung hätte ich jetzt nicht gedacht, dass das funktioniert aufgrund von char/string
Naja, wollte jetzt gerne meine Lösung präsentieren.
#include<iostream> #include<fstream> #include<string> #include<vector> #include<cmath> #include<limits> int main() { std::fstream Datei; std::string Dateiname; std::cin >> Dateiname; // Datei einlesen (Pfad angeben) Datei.open(Dateiname.c_str(), std::ios::binary|std::ios::in); std::vector<double> WerteL; // vector mit Messwerten double Summe = 0; double MW = 0; double SA = 0; for (double Wert; Datei >> Wert; WerteL.push_back(Wert)) { Summe +=Wert; MW = Summe / WerteL.size(); // Mittelwert aus Summe der Messwerte / Anzahl } Datei.clear(); Datei.seekg(std::ios_base::beg); std::vector<double> WerteV; for (double Wert; Datei >> Wert; WerteV.push_back(Wert-MW)) { // vector der Messwerte mit Abweichungen zum Mittelwert füllen } double Help = 0; // Hilfsvariable Help for (unsigned int i = 0; i < WerteL.size(); i++) { Help += WerteV[i]; // Summe der Abweichungen } SA = std::sqrt( (Help * Help) / WerteV.size() ); // Berechnung Standardabweichung std::cout << "\n\nMittelwert: " << MW << "\n\nStandardabweichung: " << SA; // Ausgabe std::cin.clear(); std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); std::cin.get(); return 0; }
Ich bin zufrieden und "Mentor" auch
@SeppJ: Danke für den Tipp mit dem debuggen nochmal, hat sehr geholfenDanke für die Hilfe
EDIT:Kritik und Verbesserungsvorschläge werden natürlich immer gern geseehn, aber bitte mit entsprechender Erklärung(Tipps)
-
xStrykex schrieb:
EDIT:Kritik und Verbesserungsvorschläge werden natürlich immer gern geseehn, aber bitte mit entsprechender Erklärung(Tipps)
1. Versuche Betriebsmittel immer während der Initialisierungs-Phase anzufordern, falls möglich. D.h. mach das
Datei.open
da weg und übergib die Zeichenkette dem Konstrukror vonstd::ifstream
.
2. Wie immer, benutzte NUR das, was du brauchst. Du brauchst keinstd::fstream
, du bruachst nurstd::ifstream
.
3. Ich verstehe nicht, wieso du die Datei 2x ausliest.
4. Eine for-Schleife ist auch nur eine Anweisung, die mit einem ; beendet werden kann. Eine leere Verbundanweisung ist doch etwas sinnlos.
5. Falls es sich um eine Textdatei handelt, öffnet man diese normal nicht im Binärmodus. D.h. lassstd::ios::binary
weg.
6. Ansonsten würde ich mir mal Funktionen zu nutzen machen. Ich würde eine Funktion machen, die etwas einließt. Ich würde eine Funktion machen, die etwas berechn. Ich würde eine Funktion machen, die am Ende das Programm offen hält.
-
out schrieb:
1. Versuche Betriebsmittel immer während der Initialisierungs-Phase anzufordern, falls möglich. D.h. mach das
Datei.open
da weg und übergib die Zeichenkette dem Konstrukror vonstd::ifstream
.
2. Wie immer, benutzte NUR das, was du brauchst. Du brauchst keinstd::fstream
, du bruachst nurstd::ifstream
.Ok, hoffe ist so wie du es dir gedacht hast im folgenden Code
out schrieb:
3. Ich verstehe nicht, wieso du die Datei 2x ausliest.
Ich habe mir gedacht, zweimal auslesen, da ich die Werte zweimal(einmal umgerechnet & in zwei verschiedene Vektoren schreibe) nutze?
out schrieb:
4. Eine for-Schleife ist auch nur eine Anweisung, die mit einem ; beendet werden kann. Eine leere Verbundanweisung ist doch etwas sinnlos.
5. Falls es sich um eine Textdatei handelt, öffnet man diese normal nicht im Binärmodus. D.h. lassstd::ios::binary
weg.Erledigt
out schrieb:
6. Ansonsten würde ich mir mal Funktionen zu nutzen machen. Ich würde eine Funktion machen, die etwas einließt. Ich würde eine Funktion machen, die etwas berechn. Ich würde eine Funktion machen, die am Ende das Programm offen hält.
Ich versuch mich dran, sobald die ersten fünf Punkte erledigt sind
EDIT: Code vergessen
#include<iostream> #include<fstream> #include<string> #include<vector> #include<cmath> #include<limits> int main() { std::string Dateiname; std::cin >> Dateiname; std::ifstream Datei(Dateiname.c_str(), std::ios::in); // Datei einlesen (Pfad angeben) std::vector<double> WerteL; // vector mit Messwerten double Summe = 0; double MW = 0; double SA = 0; for (double Wert; Datei >> Wert; WerteL.push_back(Wert)) { Summe +=Wert; MW = Summe / WerteL.size(); // Mittelwert aus Summe der Messwerte / Anzahl } Datei.clear(); Datei.seekg(std::ios_base::beg); std::vector<double> WerteV; for (double Wert; Datei >> Wert; WerteV.push_back(Wert-MW)); // vector der Messwerte mit Abweichungen zum Mittelwert füllen double Help = 0; // Hilfsvariable Help for (unsigned int i = 0; i < WerteL.size(); i++) { Help += WerteV[i]; // Summe der Abweichungen } SA = std::sqrt( (Help * Help) / WerteV.size() ); // Berechnung Standardabweichung std::cout << "\n\nMittelwert: " << MW << "\n\nStandardabweichung: " << SA; // Ausgabe std::cin.clear(); std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); std::cin.get(); return 0; }
-
Der Algorithmus ist noch nicht so toll:
Zeile 21: Wieso ist die in der Schleife drin? Denk mal nach, was bei jedem Durchlauf passiert und ob das wohl auch einfacher geht.
Zeile 27-28: Du hast doch die Werte alle schon in einem Container gespeichert! Selbst wenn du einen zweiten Container haben wolltest (wozu?), wieso kopierst du dann nicht den ersten Container?Stil:
Zeile 12: ios::in ist bei ifstream schon vorgegeben, kannst du weglassen. Was soll man auch anderes mit einem ifstream machen?
Zeile 30: Warum "Help"? Das ist die Summe der Abweichungsquadrate.
-
SeppJ schrieb:
Der Algorithmus ist noch nicht so toll:
Zeile 21: Wieso ist die in der Schleife drin? Denk mal nach, was bei jedem Durchlauf passiert und ob das wohl auch einfacher geht.Hab die Zeile mal aus der for-Schleife gepackt, dann kommt aber beim Mittelwert eine Ganzzahl bei raus(zumindest in der Ausgabe und die Standardabweichung wird komplett falsch berechnet. Woran liegt das, an dem "WerteL.size()"? Kann mir das grade nicht erklären
SeppJ schrieb:
Zeile 27-28: Du hast doch die Werte alle schon in einem Container gespeichert! Selbst wenn du einen zweiten Container haben wolltest (wozu?), wieso kopierst du dann nicht den ersten Container?
Stil:
Zeile 12: ios::in ist bei ifstream schon vorgegeben, kannst du weglassen. Was soll man auch anderes mit einem ifstream machen?
Zeile 30: Warum "Help"? Das ist die Summe der Abweichungsquadrate.Hast vollkommen Recht, sind unnötig und wurden entfernt
-
xStrykex schrieb:
SeppJ schrieb:
Der Algorithmus ist noch nicht so toll:
Zeile 21: Wieso ist die in der Schleife drin? Denk mal nach, was bei jedem Durchlauf passiert und ob das wohl auch einfacher geht.Hab die Zeile mal aus der for-Schleife gepackt, dann kommt aber beim Mittelwert eine Ganzzahl bei raus(zumindest in der Ausgabe und die Standardabweichung wird komplett falsch berechnet. Woran liegt das, an dem "WerteL.size()"? Kann mir das grade nicht erklären
Vermutlich weil du noch andere Sachen geändert hast. Zeig Code!
-
Eigentlich nicht großartig, wollte erstmal nur verbessern/optimieren und anschließend mich an den Funktionen (wie out erwähnte) versuchen
#include<iostream> #include<fstream> #include<string> #include<vector> #include<cmath> #include<limits> int main() { std::string Dateiname; std::cin >> Dateiname; std::ifstream Datei(Dateiname.c_str()); // Datei einlesen (Pfad angeben) std::vector<double> WerteL; // vector mit Messwerten double Summe = 0; double MW = 0; double SA = 0; for (double Wert; Datei >> Wert; WerteL.push_back(Wert)) { Summe +=Wert; } MW = Summe / WerteL.size(); // Mittelwert aus Summe der Messwerte / Anzahl , hier wuerde es jetzt stehen for (unsigned int i = 0; i < WerteL.size(); i++) { SA += WerteL[i]-MW; // Summe der Abweichungen } SA = std::sqrt( (SA * SA) / WerteL.size() ); // Berechnung Standardabweichung std::cout << "\n\nMittelwert: " << MW << "\n\nStandardabweichung: " << SA; // Ausgabe std::cin.clear(); std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); std::cin.get(); return 0; }
-
Ich kann das Problem nur teilweise nachvollziehen. Der Mittelwert ist bei mir weder eine Ganzzahl noch ist er falsch. Passt haargenau. Bist du sicher, dass überhaupt eine Datei geöffnet und gelesen wird? Oder ist der Mittelwert bei deinen Daten zufällig eine Ganzzahl? Oder sieht deine Datei eben doch anders aus als du behauptet hast (Kommas zwischen den Zahlen?) so dass nur ein Wert gelesen wird?
Insgesamt ist das mal wieder ein Fall für den Debugger oder ein paar Testausgaben.Die Standardabweichung wird weiterhin falsch berechnet. Das habe ich dir zwar schon auf Seite 1 mal gesagt und du hast richtigerweise etwas von "quadrieren" gemurmelt, aber du hast es niemals umgesetzt:
a²+b² != (a+b)²
Siebte Klasse.
-
SeppJ schrieb:
Bist du sicher, dass überhaupt eine Datei geöffnet und gelesen wird?
Ja, es wird die richtige Datei gelesen.
SeppJ schrieb:
Oder ist der Mittelwert bei deinen Daten zufällig eine Ganzzahl?
Nein, der Mittelwert ist keine Ganzzahl. Habe die Frage auch etwas ungeschickt gestellt, meinte, dass die Ausgabe eine Ganzzahl ist, obwohl sie keine ist(Debugger zeigt richtige Zahl an).Mit dem Debugger arbeite ich jetzt die ganze Zeit, seit du mir den empfohlen hast.
Habe es jetzt mit Testausgaben probiert. Und dabei stellt sich mir die Frage:
Bis zu wievielen Nachkommastellen gibt double standardmäßig aus?
Sieht mir nach 3 Nachkommastellen aus (den "Tests" zufolge). Vllt sollte ich dann einfach setprecision nehmen..SeppJ schrieb:
Oder sieht deine Datei eben doch anders aus als du behauptet hast (Kommas zwischen den Zahlen?) so dass nur ein Wert gelesen wird?
Ja, in der Datei befinden sich ausschließlich Punkte zwischen den Zahlen.
SeppJ schrieb:
a²+b² != (a+b)²
Siebte Klasse.Ja, tut mir Leid, hast wieder Recht.
Sobald die Aufgabe als korrekt abgestempelt wurde, habe ich mir darum keine Sorgen mehr gemacht.Sollte jetzt aber alles richtig sein.
#include<iostream> #include<fstream> #include<string> #include<vector> #include<cmath> #include<limits> int main() { std::string Dateiname; std::cin >> Dateiname; std::ifstream Datei(Dateiname.c_str()); // Datei einlesen (Pfad angeben) std::vector<double> WerteL; // vector mit Messwerten double Summe = 0; double MW = 0; double SA = 0; for (double Wert; Datei >> Wert; WerteL.push_back(Wert)) { Summe +=Wert; } MW = Summe / WerteL.size(); // Mittelwert aus Summe der Messwerte / Anzahl for (unsigned int i = 0; i < WerteL.size(); i++) { SA += ((WerteL[i]-MW)*(WerteL[i]-MW)); } SA = std::sqrt(SA / WerteL.size() ); std::cout << "\n\nMittelwert: " << MW << "\n\nStandardabweichung: " << SA; // Ausgabe std::cin.clear(); std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); std::cin.get(); return 0; }
Ich hoffe, es sind keine Flüchtigkeitsfehler mehr drin.
Auf jeden Fall vielen Dank für deine Mühe
EDIT: Ok, war reiner Rundungs"fehler" beim Mittelwert. Denke mal die Frage hat sich mit "standardmäßig 3 Nachkommastellen" für double erledigt
-
xStrykex schrieb:
Habe es jetzt mit Testausgaben probiert. Und dabei stellt sich mir die Frage:
Bis zu wievielen Nachkommastellen gibt double standardmäßig aus?
Sieht mir nach 3 Nachkommastellen aus (den "Tests" zufolge). Vllt sollte ich dann einfach setprecision nehmen..Standard ist eine Rundung auf 7 Stellen, wobei aber folgende Nullen abgeschnitten werden.
Das heißt, 0.3999999999 wird als 0.4 ausgegeben, sofern man nicht mit setprecision & Co. (guck dir mal fixed, scientific und andere Manipulatoren an) etwas anderes einstellt.
EDIT: Ok, war reiner Rundungs"fehler" beim Mittelwert. Denke mal die Frage hat sich mit "standardmäßig 3 Nachkommastellen" für double erledigt
Das heißt, es funktioniert? Wie gesagt ist Standard 7.