¿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ó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"
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
Usar notación de punto flotante fijo
Establece el
floatfield
indicador de formato para la secuencia str enfixed
.Cuando
floatfield
se establece enfixed
, los valores de punto flotante se escriben usando notación de punto fijo: el valor se representa exactamente con tantos dígitos en la parte decimal como se especifica en el campo de precisión (precision
) y sin parte de exponente.
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
}
El método habitual para hacer este tipo de cosas es "imprimir en una cadena". En C ++ eso significa usar std::stringstream
algo como:
std::stringstream ss;
ss << std::fixed << std::setprecision(2) << number;
std::string mystring = ss.str();
snprintf
mejor 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_fp
funcionalidad subyacente , es bastante extraño que demore mucho más tiempo stringstream
, ya que realmente no debería hacerlo.
Puede usar la fmt::format
función de la biblioteca {fmt} :
#include <fmt/core.h>
int main()
std::string s = fmt::format("{:.2f}", 3.14159265359); // s == "3.14"
}
donde 2
es 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 %
.
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 rounded
rinde:
3.14
El código convierte todo el flotante en una cadena, pero corta todos los caracteres 2 caracteres después del "."
number + 0.005
en 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.462997
Nota: 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();
}