¿Cómo se convierte un flotante en una cadena en C ++ mientras se especifica la precisión y el número de dígitos decimales?
Por ejemplo: 3.14159265359 -> "3.14"
                    
                        c++
                                string
                                floating-point
                                
                    
                    
                        Shannon Matthews
fuente
                
                fuente

Respuestas:
Una forma típica sería usar
stringstream:#include <iomanip> #include <sstream> double pi = 3.14159265359; std::stringstream stream; stream << std::fixed << std::setprecision(2) << pi; std::string s = stream.str();Ver fijo
y setprecision .
Para conversiones de propósito técnico , como almacenar datos en archivos XML o JSON, C ++ 17 define la familia de funciones to_chars .
Suponiendo un compilador compatible (que carecemos en el momento de escribir este artículo), se puede considerar algo como esto:
#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 }fuente
El método habitual para hacer este tipo de cosas es "imprimir en una cadena". En C ++ eso significa usar
std::stringstreamalgo como:std::stringstream ss; ss << std::fixed << std::setprecision(2) << number; std::string mystring = ss.str();fuente
Otra opcion es
snprintf:double pi = 3.1415926; std::string s(16, '\0'); auto written = std::snprintf(&s[0], s.size(), "%.2f", pi); s.resize(written);Demo . Se debe agregar el manejo de errores, es decir, verificar
written < 0.fuente
snprintfmejor en este caso? Por favor explique ... Ciertamente no será más rápido, producirá menos código [He escrito una implementación de printf, es bastante compacta con poco menos de 2000 líneas de código, pero con macro expansiones llega a alrededor de 2500 líneas]__printf_fpfuncionalidad subyacente , es bastante extraño que demore mucho más tiempostringstream, ya que realmente no debería hacerlo.Puede usar la
fmt::formatfunción de la biblioteca {fmt} :#include <fmt/core.h> int main() std::string s = fmt::format("{:.2f}", 3.14159265359); // s == "3.14" }donde
2es una precisión.Esta función de formato se ha propuesto para la estandarización en C ++: P0645 . Tanto P0645 como {fmt} usan una sintaxis de cadena de formato similar a Python que es similar a
printf's pero usa{}como delimitadores en lugar de%.fuente
Aquí una solución que usa solo std. Sin embargo, tenga en cuenta que esto solo se redondea a la baja.
float number = 3.14159; std::string num_text = std::to_string(number); std::string rounded = num_text.substr(0, num_text.find(".")+3);Porque
roundedrinde:3.14El código convierte todo el flotante en una cadena, pero corta todos los caracteres 2 caracteres después del "."
fuente
number + 0.005en mi caso.Aquí proporciono un ejemplo negativo en el que desea evitar al convertir un número flotante en cadenas.
float num=99.463; float tmp1=round(num*1000); float tmp2=tmp1/1000; cout << tmp1 << " " << tmp2 << " " << to_string(tmp2) << endl;Usted obtiene
99463 99.463 99.462997Nota: la variable num puede ser cualquier valor cercano a 99.463, obtendrá la misma impresión. El punto es evitar la conveniente función de c ++ 11 "to_string". Me tomó un tiempo salir de esta trampa. La mejor forma son los métodos stringstream y sprintf (lenguaje C). C ++ 11 o posterior debe proporcionar un segundo parámetro como el número de dígitos después del punto flotante para mostrar. En este momento, el valor predeterminado es 6. Estoy planteando esto para que otros no pierdan el tiempo en este tema.
Escribí mi primera versión, avíseme si encuentra algún error que deba solucionarse. Puede controlar el comportamiento exacto con el iomanipulador. Mi función es para mostrar el número de dígitos después del punto decimal.
string ftos(float f, int nd) { ostringstream ostr; int tens = stoi("1" + string(nd, '0')); ostr << round(f*tens)/tens; return ostr.str(); }fuente