2015-03-22 7 views
40

Wie konvertiert man ein Float in eine Zeichenfolge in C++ und gibt dabei die Genauigkeit & Anzahl der Dezimalstellen an?Konvertieren Float in String mit festgelegter Genauigkeit und Anzahl der Dezimalstellen?

Zum Beispiel: 3.14159265359 -> "3.14"

+0

Warum erstellen Sie keine temporäre Gleitkommazahl mit der angegebenen Genauigkeit und konvertieren sie dann in eine Zeichenfolge? – Gilad

+0

@Gilad Der 'temp float' hat keine 'spezifizierte Genauigkeit' und es gibt Fälle, in denen ein solcher Ansatz nicht funktioniert. Diese Frage ist im Grunde wie die Frage "Was entspricht dem Format"% .2f "? – user2864740

+1

Siehe http://stackoverflow.com/questions/14432043/c-float-formatting, wenn dies nur für IO erforderlich ist. – user2864740

Antwort

59
#include <iomanip> // setprecision 
#include <sstream> // stringstream 

double pi = 3.14159265359; 
stringstream stream; 
stream << fixed << setprecision(2) << pi; 
string s = stream.str(); 

Siehe fixed

Verwenden fester Gleitkommanotation

Stellt den floatfield Format-Flag für den str Strom fixed.

Wenn floatfield zu fixed gesetzt ist, Gleitkommawerte geschrieben wird unter Verwendung von Festkommaschreibweise: der Wert wird in dem Dezimalteil mit genau so vielen Ziffern dargestellt, wie durch das Präzisionsfeld spezifizierte (precision) und mit keinem Exponententeil.

und setprecision.

18

Die übliche Methode, um so etwas zu machen, ist "auf Zeichenfolgen zu drucken". In C++ das heißt mit std::stringstream so etwas wie:

std::stringstream ss; 
ss << std::fixed << std::setprecision(2) << number; 
std::string mystring = ss.str(); 
5

Eine weitere Option ist snprintf:

double pi = 3.1415926; 

std::string s(16, '\0'); 
auto written = std::snprintf(&s[0], s.size(), "%.2f", pi); 
s.resize(written); 

Demo. Fehlerbehandlung sollte hinzugefügt werden, d. H. Prüfung auf written < 0.

+0

Warum sollte "snprintf" in diesem Fall besser sein?Bitte erklären ... Es wird sicherlich nicht schneller sein, produzieren weniger Code [Ich habe eine printf-Implementierung geschrieben, es ist ziemlich kompakt bei knapp 2000 Zeilen Code, aber mit Makro-Erweiterungen zu rund 2500 Zeilen] –

+0

@MatsPetersson ich stark glaube, dass es schneller sein wird. Das ist der Grund, warum ich diese Antwort überhaupt erst gemacht habe. – Columbo

+0

@MatsPetersson Ich habe Messungen durchgeführt (GCC 4.8.1, -O2), die anzeigen, dass snprintf tatsächlich weniger Zeit benötigt, um Faktor 17/22. Ich werde den Code in Kürze hochladen. – Columbo

0

Hier biete ich ein negatives Beispiel, wo Sie vermeiden möchten, wenn Floating-Nummer in Zeichenfolgen konvertiert.

float num=99.463; 
float tmp1=round(num*1000); 
float tmp2=tmp1/1000; 
cout << tmp1 << " " << tmp2 << " " << to_string(tmp2) << endl; 

Sie erhalten

99463 99.463 99.462997 

Hinweis: Die Variable num jeder Wert in der Nähe 99,463 sein können, werden Sie den gleichen Druck raus. Der Punkt ist, die bequeme C++ 11 "to_string" -Funktion zu vermeiden. Ich brauchte eine Weile, um diese Falle zu lösen. Der beste Weg ist die Stringstream- und Sprintf-Methode (C-Sprache). C++ 11 oder neuer sollte einen zweiten Parameter als die Anzahl der Ziffern nach dem Gleitkomma zur Verfügung stellen. Im Moment ist der Standardwert 6. Ich setze das so, dass andere keine Zeit zu diesem Thema verschwenden.

Ich schrieb meine erste Version, bitte lassen Sie mich wissen, wenn Sie einen Fehler finden, der behoben werden muss. Sie können das genaue Verhalten mit dem Iomanipulator steuern. Meine Funktion zeigt die Anzahl der Nachkommastellen an.

string ftos(float f, int nd) { 
    ostringstream ostr; 
    int tens = stoi("1" + string(nd, '0')); 
    ostr << round(f*tens)/tens; 
    return ostr.str(); 
} 
Verwandte Themen