Wie konvertiert man einen Float in eine Zeichenfolge in C ++, während man die Genauigkeit und Anzahl der Dezimalstellen angibt?
Beispielsweise: 3.14159265359 -> "3.14"
Wie konvertiert man einen Float in eine Zeichenfolge in C ++, während man die Genauigkeit und Anzahl der Dezimalstellen angibt?
Beispielsweise: 3.14159265359 -> "3.14"
Antworten:
Ein typischer Weg wäre zu verwenden stringstream
:
#include <iomanip>
#include <sstream>
double pi = 3.14159265359;
std::stringstream stream;
stream << std::fixed << std::setprecision(2) << pi;
std::string s = stream.str();
Siehe behoben
Verwenden Sie eine feste Gleitkommanotation
Setzt das
floatfield
Format-Flag für den str- Stream auffixed
.Wenn diese
floatfield
Option auf gesetzt istfixed
, werden Gleitkommawerte in Festkommanotation geschrieben: Der Wert wird mit genau so vielen Stellen im Dezimalteil dargestellt, wie im Genauigkeitsfeld (precision
) angegeben, und ohne Exponententeil.
und setprecision .
Für Konvertierungen von technischen Zwecken wie das Speichern von Daten in XML- oder JSON-Dateien definiert C ++ 17 die Funktionsfamilie to_chars .
Unter der Annahme eines kompatiblen Compilers (der uns zum Zeitpunkt des Schreibens fehlt) kann Folgendes in Betracht gezogen werden:
#include <array>
#include <charconv>
double pi = 3.14159265359;
std::array<char, 128> buffer;
auto [ptr, ec] = std::to_chars(buffer.data(), buffer.data() + buffer.size(), pi,
std::chars_format::fixed, 2);
if (ec == std::errc{}) {
std::string s(buffer.data(), ptr);
// ....
}
else {
// error handling
}
Die übliche Methode, um so etwas zu tun, ist "Print to String". In C ++ bedeutet das std::stringstream
Folgendes:
std::stringstream ss;
ss << std::fixed << std::setprecision(2) << number;
std::string mystring = ss.str();
snprintf
es in diesem Fall besser? Bitte erklären Sie ... Es wird sicherlich nicht schneller sein, weniger Code produzieren [Ich habe eine printf-Implementierung geschrieben, es ist ziemlich kompakt mit knapp 2000 Codezeilen, aber mit Makroerweiterungen werden es ungefähr 2500 Zeilen]
__printf_fp
Funktionalität verwenden - es ist ziemlich seltsam, dass es so viel länger dauert stringstream
, als es eigentlich nicht sein sollte.
Sie können die fmt::format
Funktion aus der {fmt} -Bibliothek verwenden :
#include <fmt/core.h>
int main()
std::string s = fmt::format("{:.2f}", 3.14159265359); // s == "3.14"
}
Wo 2
ist eine Präzision.
Diese Formatierungsfunktion wurde zur Standardisierung in C ++: P0645 vorgeschlagen . Sowohl P0645 als auch {fmt} verwenden eine Python-ähnliche String-Syntax, die der von printf
's ähnelt, jedoch {}
anstelle von Trennzeichen verwendet wird %
.
Hier eine Lösung mit nur std. Beachten Sie jedoch, dass dies nur abrundet.
float number = 3.14159;
std::string num_text = std::to_string(number);
std::string rounded = num_text.substr(0, num_text.find(".")+3);
Denn rounded
es ergibt:
3.14
Der Code konvertiert den gesamten Float in einen String, schneidet jedoch alle Zeichen 2 Zeichen nach dem "."
number + 0.005
in meinem Fall.
Hier gebe ich ein negatives Beispiel, bei dem Sie vermeiden möchten, wenn Sie eine schwebende Zahl in Zeichenfolgen konvertieren.
float num=99.463;
float tmp1=round(num*1000);
float tmp2=tmp1/1000;
cout << tmp1 << " " << tmp2 << " " << to_string(tmp2) << endl;
Du erhältst
99463 99.463 99.462997
Hinweis: Die Variable num kann ein beliebiger Wert nahe 99,463 sein. Sie erhalten den gleichen Ausdruck. Der Punkt ist, die bequeme c ++ 11 "to_string" -Funktion zu vermeiden. Ich habe eine Weile gebraucht, um diese Falle zu überwinden. Der beste Weg ist die Stringstream- und Sprintf-Methode (C-Sprache). C ++ 11 oder neuer sollte einen zweiten Parameter als Anzahl der Stellen nach dem anzuzeigenden Gleitkomma bereitstellen. Im Moment ist die Standardeinstellung 6. Ich setze dies so, dass andere keine Zeit mit diesem Thema verschwenden.
Ich habe meine erste Version geschrieben. 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 besteht darin, die Anzahl der Stellen nach dem Dezimalpunkt anzuzeigen.
string ftos(float f, int nd) {
ostringstream ostr;
int tens = stoi("1" + string(nd, '0'));
ostr << round(f*tens)/tens;
return ostr.str();
}