Double-Wert Runden.
-
Hallo alle zusammen.
Bitte nicht böse sein über die Frage, aber ich habe nach langer Recherche nix über Suchfunktion oder ähnliches heraus gefunden, was mein Problem löst.
Also...
Ich habe einen Double-Wert und will den runden, auf oder ab ist egal.
Und zwar am liebsten auf 3 Stellen nach dem Komma (darum geht floor und ceil nicht) und der Exponent soll beibehalten werden (siehe Beispiel 2 weiter unten)!Hoffe das ist verständlich genug ausgedrückt.
Als Beispiel:
runde(1,23456) = 1,234
runde(1,23456 E-10) = 1,234 E-10Also mit den normalen Methoden würde ja ja 1,23456 E-10 abgerundet 0,000 ergeben.
Das soll es aber nicht.
Kennt da jemand eine Funktion, die man da verwenden kann?
Ich würde mir ungern da was selbst zusammenbasteln. Das ist für meine Diplomarbeit und darf desswegen kein gehacke sein :).Vielen Dank schonmal und beste Grüße
Max
-
Max3000 schrieb:
Als Beispiel:
runde(1,23456) = 1,234
runde(1,23456 E-10) = 1,234 E-10.. sagst Du uns noch fix, wie
runde(0,123456) = ??
gerundet werden soll? Und warum willst Du runden - nur für die Ausgabe?
-
Schon mal auf Englisch übersetzt? Wenn du cmath incudest, dann gibt es die Funktion round.
#include <cmath> using namespace std; int main() { double ungerundet, gerundet; ungerundet = 3.576774; gerundet = round(ungerundet, 3) // 3.577 return 0; }
-
Das round mit 2 Argumenten hab ich gar nicht.
Ohne cmath sagt der mirtoo many arguments to function double round(double)
und mit cmath und std::round
round is not a member of std
Ohne std das gleiche wie ohne c-math.
Also eigentlich will ich nur für die Ausgabe die Werte gerundet haben.
Hätte ja dann an die [X]printf-Sachen gedacht, aber das ist ja kein C++, oder?
-
-
0,12345 soll gerundet entweder
1,234 E-1
oder
0,123sein. Das ist mir dann eigentlich egal. Wahrscheinlich passt die erste Variante besser zum Rest.
-
Alternativ wären da noch 2 selbstgeschriebene Funktionen:
#include <cmath> #include <iostream> using namespace std; int runden(double wert) { return (int) (wert + ((wert < 0)? - 0.5 : 0.5)); } double runden(double wert, int nachkommastellen) { return ((int) ((wert * pow(10.0, nachkommastellen)) + ((wert < 0)? - 0.5 : 0.5))) / pow(10.0, nachkommastellen); }
Extrem Kurzfassung, funktioniert, rundet richtig und ist am effiktivsten!!!
Ich habs getestet! Ich hoffe, ich konnte dir helfen. Wenn du eine Erklärung willst, dann bitte per PN, ich Schreibs dann in der Langfassung hier rein!
-
Jetzt hab ichs.
Für die Aufgabe reicht jastd::cout.precision(4);
Habe ein Programm was diverse Sachen berechnet und will die Werte für jede Iteration Tabellarisch darstellen mit
std::cout << wert1 << '\t' << wert2 << '\t' << ...
Aber irgendwie machts das doch nicht so wie ich will, weil 4 Ziffern + 1 Komma + 1 mal E + 1 Minus + 2 Ziffern für den Exponent doch länger als ein Tabulator sind.
Hat schon mal jemand sowas gemacht und kann mir da vielleicht einen kleinen Tipp geben?So sieht meine Tabelle jetzt aus:
Iteration |u(s)-u_ex| EOC |Pu(s)-u_ex| |J(Pu(s))-J(u(s))| 1 4.414 0.1799 4.811e-06 0.03525 2 4.38 0.01108 4.738e-06 0.03497 3 4.314 0.02191 4.596e-06 0.03442 4 4.188 0.04285 4.331e-06 0.03337 5 3.956 0.08206 3.866e-06 0.03146 6 3.562 0.1513 3.135e-06 0.02821 7 2.971 0.262 2.181e-06 0.02339 8 2.23 0.4137 1.229e-06 0.01742 9 1.488 0.5837 5.474e-07 0.01153 10 0.8935 0.7359 1.974e-07 0.006877 11 0.4966 0.8473 6.1e-08 0.003805 12 0.263 0.9171 1.711e-08 0.002009 13 0.1355 0.9567 4.542e-09 0.001034 14 0.0688 0.9779 1.171e-09 0.0005244 15 0.03467 0.9888 2.973e-10 0.0002641 16 0.0174 0.9944 7.491e-11 0.0001325 17 0.008718 0.9972 1.88e-11 6.64e-05 18 0.004363 0.9986 4.709e-12 3.323e-05 19 0.002183 0.9993 1.178e-12 1.662e-05 20 0.001092 0.9996 2.947e-13 8.313e-06 21 0.0005459 0.9998 7.37e-14 4.157e-06 22 0.0002729 0.9999 1.842e-14 2.079e-06 23 0.0001365 1 4.605e-15 1.039e-06 24 6.824e-05 1 1.151e-15 5.197e-07 25 3.412e-05 1 2.874e-16 2.598e-07 26 1.706e-05 1 7.169e-17 1.299e-07 27 8.53e-06 1 1.784e-17 6.496e-08 28 4.265e-06 1 4.421e-18 3.248e-08 29 2.132e-06 1 1.086e-18 1.624e-08 30 1.066e-06 1 2.62e-19 8.12e-09 31 5.331e-07 1 6.077e-20 4.06e-09 32 2.666e-07 1 1.303e-20 2.03e-09 33 1.333e-07 1 2.287e-21 1.015e-09 34 6.664e-08 1 2.161e-22 5.075e-10 35 3.332e-08 1 4.069e-24 2.538e-10 36 1.666e-08 1 1.076e-22 1.269e-10 37 8.331e-09 0.9998 2.019e-22 6.344e-11 38 4.168e-09 0.9992 2.726e-22 3.172e-11 39 2.089e-09 0.9966 3.11e-22 1.586e-11 40 1.054e-09 0.9862 3.263e-22 7.927e-12
Man sieht ja wie bei Iteration 17 dann die 2. Spalte zu groß wird und dann alles eins weiter rückt als es eigentlich soll.
Schönen Gruß und Danke für die Antworten.
-
In String mwandeln und Zeichen zählen. Das kriegst sogar du hin. Du musst dann nurnoch die Länge des Tabulators errausfinden. Hast du jetzt eigentlich schon die Funktionen ausprobiert?
-
Die Funktion die du gepostet hast, rundet zwar
1,23456 auf 1,234,
aber nicht wie ich es gern hätte
1,23456 E-10 auf 1,234 E-10
sondern es rundet
1,23456 E-10 auf 0.
Ich brauch den Exponent :D.Und Zeichen zählen wollte ich jetzt eigentlich nicht erst :D.
Da muss es doch irgendetwa schönes geben was man verwenden kann.
Wenn 80% des Codes für die Formatierung der Konsolenausgabe drauf geht ist das nicht das, wonach ich gesucht habe.
Vielleicht schreib ich mir selber mal ne Klasse, die das macht. "ConsoleTable" oder sowas :).Vielen Dank für die Hilfe.
-
Max3000 schrieb:
Die Funktion die du gepostet hast, rundet zwar
1,23456 auf 1,234,
aber nicht wie ich es gern hätte
1,23456 E-10 auf 1,234 E-10
sondern es rundet
1,23456 E-10 auf 0.
Ich brauch den Exponent :D.Und Zeichen zählen wollte ich jetzt eigentlich nicht erst :D.
Da muss es doch irgendetwa schönes geben was man verwenden kann.
Wenn 80% des Codes für die Formatierung der Konsolenausgabe drauf geht ist das nicht das, wonach ich gesucht habe.
Vielleicht schreib ich mir selber mal ne Klasse, die das macht. "ConsoleTable" oder sowas :).Vielen Dank für die Hilfe.
Ja, 1,23456 E-10 ist ja 0,000000000123456. Und wenn du eine genauigkeit von 3 Nachkommastellen eingibst, dann muss das ja 0 sein. Rechne mal nach! Die Funktion funktioniert schon, aber wenn du das so haben willst, dann musst du dir selber etwas ausdenken!
-
Ich machs erstmal mit cout.precision(4).
Das reicht erstmal.
Die Verschiebung der Tabulatoren nehm ich erstmal in Kauf.
Danke für die Unterstützung.
-
ich hab die Funktion umgeschrieben. Jetzt stellt sie nach der Form um, die du hast, also 1.23E-2 zu 1.2E-2 und 1.23E2 zu 1.2E2.
double runden2(double wert, int nachkommastellen) { int i = 0, j = 0; for(; wert < 1; i++) wert *= 10; for(; wert > 10; j++) wert /= 10; return ((int) ((wert * pow(10.0, nachkommastellen)) + ((wert < 0)? - 0.5 : 0.5))) / pow(10.0, nachkommastellen + i - j); }
ich hoffe, di Funktion ist besser. Auf jedenfall schneller!
-
guck dir mal setw an
-
Danke. Das war genau das was ich gesucht habe. Damit klappts. Vielen Dank für den Hinweis.
-
Ich ahb auch eine:
#include <cmath> #include <string> #include <sstream> using namespace std; double runden( double wert, int nachkommastellen ) { return ((int) ((wert * pow(10.0, nachkommastellen)) + ((wert < 0)? - 0.5 : 0.5))) / pow(10.0, nachkommastellen); } double runden2( double wert, int nachkommastellen ) { int i = 0, j = 0; for(; wert < 1; i++) wert *= 10; for(; wert > 10; j++) wert /= 10; return ((int) ((wert * pow(10.0, nachkommastellen)) + ((wert < 0)? - 0.5 : 0.5))) / pow(10.0, nachkommastellen + i - j); } string runden3( double wert, int nachkommastellen, int min_laenge = 0, bool normal_runden = true, bool m_laenge = false, int max_laenge = 0 ) { string str = double_to_string(normal_runden? runden(wert, nachkommastellen) : runden2(wert, nachkommastellen)); int len = str.length(); for(;len < min_laenge; len++) str += " "; if(m_laenge) for(;len > max_laenge; len--) str = str.erase(len); return str; }
Für deine Zwecke müsstest du das so machen:
datei << runden3(dein_wert, nachkommastellen, /*Beispiel:*/15, false);
Zur Erklärung:
double wert:
Erklärt sich von selbst!
int nachkommastellen:
Auch!
int min_laenge:
Hier kannst du die minimale Länge des Zurückgegebenen Strings angeben.
bool normal_runden
Stell einfach auf false!
Den Rest brauchst du nicht!