Come si converte un float in una stringa in C ++ specificando la precisione e il numero di cifre decimali?
Per esempio: 3.14159265359 -> "3.14"
Come si converte un float in una stringa in C ++ specificando la precisione e il numero di cifre decimali?
Per esempio: 3.14159265359 -> "3.14"
Risposte:
Un modo tipico sarebbe usare stringstream:
#include <iomanip>
#include <sstream>
double pi = 3.14159265359;
std::stringstream stream;
stream << std::fixed << std::setprecision(2) << pi;
std::string s = stream.str();
Vedi fisso
Usa la notazione a virgola mobile fissa
Imposta il
floatfieldflag di formato per il flusso str sufixed.Quando
floatfieldè impostato sufixed, i valori a virgola mobile vengono scritti utilizzando la notazione a virgola fissa: il valore è rappresentato esattamente con tante cifre nella parte decimale come specificato dal campo di precisione (precision) e senza parte esponente.
Per conversioni di scopi tecnici , come la memorizzazione di dati in file XML o JSON, C ++ 17 definisce la famiglia di funzioni to_chars .
Supponendo un compilatore conforme (che ci manca al momento della scrittura), si può considerare qualcosa di simile:
#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
}
Il metodo consueto per fare questo genere di cose è "stampare su una stringa". In C ++ questo significa usare std::stringstreamqualcosa come:
std::stringstream ss;
ss << std::fixed << std::setprecision(2) << number;
std::string mystring = ss.str();
snprintfmeglio in questo caso? Spiega ... Certamente non sarà più veloce, produrrà meno codice [Ho scritto un'implementazione printf, è abbastanza compatto con poco meno di 2000 righe di codice, ma con espansioni macro arriva a circa 2500 righe]
__printf_fpfunzionalità sottostante - è piuttosto strano che ci voglia molto più tempo stringstream, come non dovrebbe davvero.
Puoi usare C ++ 20 std::formato la fmt::formatfunzione dalla libreria {fmt} , std::formatsi basa su:
#include <fmt/core.h>
int main()
std::string s = fmt::format("{:.2f}", 3.14159265359); // s == "3.14"
}
dov'è 2una precisione.
Ecco una soluzione che utilizza solo std. Tuttavia, si noti che questo viene solo arrotondato per difetto.
float number = 3.14159;
std::string num_text = std::to_string(number);
std::string rounded = num_text.substr(0, num_text.find(".")+3);
Perché roundedproduce:
3.14
Il codice converte l'intero float in stringa, ma taglia tutti i caratteri 2 caratteri dopo il "."
number + 0.005nel mio caso.
Qui sto fornendo un esempio negativo in cui vuoi evitare quando converti il numero mobile in stringhe.
float num=99.463;
float tmp1=round(num*1000);
float tmp2=tmp1/1000;
cout << tmp1 << " " << tmp2 << " " << to_string(tmp2) << endl;
Ottieni
99463 99.463 99.462997
Nota: la variabile num può essere qualsiasi valore vicino a 99.463, otterrai la stessa stampa. Il punto è evitare la comoda funzione c ++ 11 "to_string". Mi ci è voluto un po 'per uscire da questa trappola. Il modo migliore sono i metodi stringstream e sprintf (linguaggio C). C ++ 11 o più recente dovrebbe fornire un secondo parametro come numero di cifre dopo il punto mobile da mostrare. In questo momento il valore predefinito è 6. Sto postulando questo in modo che altri non perdano tempo su questo argomento.
Ho scritto la mia prima versione, per favore fammi sapere se trovi qualche bug che deve essere corretto. Puoi controllare il comportamento esatto con iomanipulator. La mia funzione è mostrare il numero di cifre dopo il punto decimale.
string ftos(float f, int nd) {
ostringstream ostr;
int tens = stoi("1" + string(nd, '0'));
ostr << round(f*tens)/tens;
return ostr.str();
}