HOWTO · C++
Establecer la precisión de los números de punto flotante en C++
Este artículo muestra cómo establecer la precisión de los números de punto flotante en C++
En esta página
Para controlar cómo se escribe un valor de punto flotante en un flujo de salida de C++, use std::setprecision. En el formato predeterminado, establece las cifras significativas; combínelo con std::fixed si desea fijar la cantidad de dígitos después del separador decimal. Estos manipuladores cambian la representación que se muestra, no el valor almacenado. Use funciones de redondeo de <cmath> cuando necesite cambiar el valor en sí.
Formatear la salida de punto flotante con std::setprecision
std::setprecision, con un argumento entero, establece la precisión de las inserciones posteriores de valores de punto flotante en el flujo. Incluya <iomanip> para usar el manipulador. Con el formato de punto flotante predeterminado del flujo, la precisión indica cifras significativas y su valor predeterminado es seis. Para valores muy pequeños o muy grandes, el flujo puede elegir la notación científica. El ajuste de precisión se mantiene para las inserciones posteriores en ese flujo hasta que se cambie.
El siguiente ejemplo completo compara el formato predeterminado, tres cifras significativas, tres dígitos después del separador decimal y el redondeo de un valor antes de escribirlo. std::defaultfloat restablece el formato predeterminado del flujo; la precisión seleccionada sigue vigente. La salida observada de este ejemplo es:
Ejecute este ejemplo:
El código y las etiquetas o salidas visibles de esta sección se mantienen en inglés.
#include <cmath>
#include <iomanip>
#include <iostream>
int main() {
const double value = 123.4567;
std::cout << std::defaultfloat << std::setprecision(6)
<< "default: " << value << '\n';
std::cout << std::setprecision(3)
<< "three significant digits: " << value << '\n';
std::cout << std::fixed << std::setprecision(3)
<< "three decimal places: " << value << '\n';
std::cout << std::defaultfloat << std::setprecision(6)
<< "rounded value: " << std::round(value) << '\n';
}
default: 123.457
three significant digits: 123
three decimal places: 123.457
rounded value: 123
Elegir entre cifras significativas y posiciones decimales
Use std::setprecision(n) para indicar cifras significativas solo cuando el flujo esté en su formato de punto flotante predeterminado. Este es el formato inicial, y std::defaultfloat lo restablece después de seleccionar otro formato. Los indicadores de formato del flujo persisten: si antes se activó std::fixed, seguirá activo y hará que la precisión cuente los dígitos después del separador decimal. Para volver a contar cifras significativas, inserte std::defaultfloat antes de std::setprecision(n). Este recuento incluye los dígitos a ambos lados del separador decimal. Por ejemplo, tres cifras significativas pueden mostrar 123.4567 como aproximadamente 123 y 0.01234567 como aproximadamente 0.0123; el flujo puede usar notación exponencial cuando resulte más adecuada.
Use std::fixed << std::setprecision(n) para fijar la cantidad de dígitos después del separador decimal, como en una presentación de tipo monetario. Con tres posiciones decimales, un valor como 2.5 se muestra con tres dígitos fraccionarios. Esto solo afecta al formato: el double subyacente conserva su valor original de punto flotante binario. Para cambiar la cantidad de dígitos mostrados, vuelva a establecer la precisión en el mismo flujo.
Redondear valores con antes de formatearlos
Las funciones std::floor, std::ceil y std::round de <cmath> calculan valores distintos. std::floor(x) devuelve el mayor valor entero que no supera x, mientras que std::ceil(x) devuelve el menor valor entero que no es inferior a x. std::round(x) redondea al entero más cercano; los casos a mitad de camino se redondean alejándose de cero. Estas funciones no configuran la precisión de salida del flujo.
std::lround(x) sigue la misma regla de redondeo al entero más cercano, con los casos a mitad de camino alejándose de cero, y devuelve un long. Úsela cuando necesite un resultado entero y el resultado redondeado se pueda representar como long; std::round devuelve un valor de punto flotante. Después de calcular un valor redondeado, use por separado los manipuladores del flujo si también necesita controlar su formato de salida.
Evitar errores comunes de precisión y redondeo
No suponga que std::setprecision(2) significa dos dígitos después del separador decimal: sin std::fixed, significa dos cifras significativas. En cambio, std::fixed puede hacer que un valor muy pequeño aparezca como 0.000 al mostrar tres posiciones decimales. La representación se ha redondeado al formato elegido, pero la variable original no se ha convertido en cero.
Mantenga diferenciadas ambas operaciones: los manipuladores controlan la presentación, mientras que las funciones de <cmath> calculan un valor nuevo. Si necesita tanto un valor redondeado como una cantidad específica de posiciones decimales en la salida, aplique la función de redondeo al valor y luego formatee el flujo con std::fixed y std::setprecision.