web-dev-qa-db-fra.com

Convertir le float en chaîne avec la précision et le nombre de chiffres décimaux spécifiés?

Comment convertir un float en chaîne en C++ en spécifiant la précision et le nombre de chiffres décimaux? 

Par exemple: 3.14159265359 -> "3.14"

57
Shannon
#include <iomanip> // setprecision
#include <sstream> // stringstream

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

Voir fixe

Utiliser une notation à virgule flottante fixe

Définit l'indicateur de format floatfield pour le flux str sur fixed.

Lorsque floatfield est défini sur fixed, les valeurs en virgule flottante sont écrites en notation à virgule fixe: la valeur est représentée avec exactement autant de chiffres dans la partie décimale que celle spécifiée par le champ de précision (precision) partie exposant.

et setprecision .

84
AlexD

La méthode habituelle pour faire ce genre de chose est "print to string". En C++, cela signifie que std::stringstream ressemble à ceci:

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

Une autre option est snprintf :

double pi = 3.1415926;

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

Démo . La gestion des erreurs doit être ajoutée, c’est-à-dire en vérifiant written < 0.

8
Columbo

Vous pouvez utiliser la fonction fmt::format de la bibliothèque {fmt} :

#include <fmt/core.h>

int main()
  std::string s = fmt::format("{:.2f}", 3.14159265359); // s == "3.14"
}

2 est une précision.

Cette fonctionnalité de formatage a été proposée pour normalisation en C++: P0645 . P0645 et {fmt} utilisent tous deux une syntaxe de chaîne de format semblable à celle de printf mais utilisent {} comme délimiteurs au lieu de %.

2
vitaut

Ici, je fournis un exemple négatif où vous voulez éviter lors de la conversion d'un nombre flottant en chaînes. 

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

Vous recevez

99463 99.463 99.462997

Remarque: la variable num peut être toute valeur proche de 99,463, vous obtiendrez la même impression. Le but est d'éviter la fonction "to_string" de c ++ 11. Il m'a fallu un certain temps pour sortir de ce piège. Le meilleur moyen est d'utiliser les méthodes stringstream et sprintf (langage C). C++ 11 ou plus récent devrait fournir un deuxième paramètre indiquant le nombre de chiffres après le virgule flottante. À l'heure actuelle, la valeur par défaut est 6. Je propose cela pour que les autres ne perdent pas de temps à ce sujet.

J'ai écrit ma première version, s'il vous plaît laissez-moi savoir si vous trouvez un bug qui doit être corrigé. Vous pouvez contrôler le comportement exact avec l'iomanipulator. Ma fonction est d'afficher le nombre de chiffres après le point décimal.

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