quitar poner pantalla notacion mostrar los limitar imprimir float dev decimales datos con como cientifica c++ floating-point precision iostream cout

c++ - poner - ¿Cómo imprimo un valor doble con total precisión utilizando cout?



imprimir float con 2 decimales c++ (11)

Así que obtuve la respuesta a mi última pregunta (no sé por qué no pensé en eso). Estaba imprimiendo un double usando cout que se redondeaba cuando no lo esperaba. ¿Cómo puedo hacer que cout imprima un double con total precisión?


¿Cómo imprimo un valor double con total precisión utilizando cout?

Utilizar hexfloat o
Usa scientific y establece la precisión.

std::cout.precision(std::numeric_limits<double>::max_digits10 - 1); std::cout << std::scientific << 1.0/7.0 << ''/n''; // C++11 Typical output 1.4285714285714285e-01

Demasiadas respuestas abordan solo una de 1) base 2) diseño fijo / científico o 3) precisión. Demasiadas respuestas con precisión no proporcionan el valor adecuado necesario. De ahí esta respuesta a una vieja pregunta.

  1. En que base

Un double ciertamente se codifica utilizando la base 2. Un enfoque directo con C ++ 11 es imprimir usando std::hexfloat .
Si una salida no decimal es aceptable, hemos terminado.

std::cout << "hexfloat: " << std::hexfloat << exp (-100) << ''/n''; std::cout << "hexfloat: " << std::hexfloat << exp (+100) << ''/n''; // output hexfloat: 0x1.a8c1f14e2af5dp-145 hexfloat: 0x1.3494a9b171bf5p+144

  1. De lo contrario: ¿ fixed o scientific ?

Un double es un tipo de punto flotante , no un punto fijo .

No use std::fixed ya que no se imprime un double como cualquier cosa menos 0.000...000 . Para el double grande, imprime muchos dígitos, quizás cientos de informatividad cuestionable.

std::cout << "std::fixed: " << std::fixed << exp (-100) << ''/n''; std::cout << "std::fixed: " << std::fixed << exp (+100) << ''/n''; // output std::fixed: 0.000000 std::fixed: 26881171418161356094253400435962903554686976.000000

Para imprimir con total precisión, primero use std::scientific que "escribirá valores de punto flotante en notación científica". Observe que el valor predeterminado de 6 dígitos después del punto decimal, una cantidad insuficiente, se maneja en el siguiente punto.

std::cout << "std::scientific: " << std::scientific << exp (-100) << ''/n''; std::cout << "std::scientific: " << std::scientific << exp (+100) << ''/n''; // output std::scientific: 3.720076e-44 std::scientific: 2.688117e+43

  1. ¿Cuánta precisión (cuántos dígitos totales)?

Una codificación double con la base binaria 2 codifica la misma precisión entre varias potencias de 2. Esto suele ser de 53 bits.

[1.0 ... 2.0) hay 2 53 double diferentes,
[2.0 ... 4.0) hay 2 53 double diferentes,
[4.0 ... 8.0) hay 2 53 double diferentes,
[8.0 ... 10.0) hay 2/8 * 2 53 double diferentes.

Sin embargo, si el código se imprime en decimal con N dígitos significativos, el número de combinaciones [1.0 ... 10.0) es 9/10 * 10 N.

Cualquiera que sea la elección de N (precisión), no habrá una asignación uno a uno entre el texto double y el decimal. Si se elige una N fija, a veces será ligeramente más o menos que lo que realmente se necesita para ciertos valores double . Podríamos error en muy pocos ( a) continuación) o demasiados ( b) continuación).

3 candidatos N :

a) Use una N para que al convertir desde texto double texto lleguemos al mismo texto para todo double .

std::cout << dbl::digits10 << ''/n''; // Typical output 15

b) Use una N para que al convertir de double texto double lleguemos al mismo double para todo double .

// C++11 std::cout << dbl::max_digits10 << ''/n''; // Typical output 17

Cuando max_digits10 no está disponible, tenga en cuenta que debido a los atributos de base 2 y base 10, digits10 + 2 <= max_digits10 <= digits10 + 3 , podemos usar digits10 + 3 para asegurar que se imprimen suficientes dígitos decimales.

c) Usa una N que varíe con el valor.

Esto puede ser útil cuando el código quiere mostrar un texto mínimo ( N == 1 ) o el valor exacto de un double ( N == 1000-ish en el caso de denorm_min ). Sin embargo, dado que esto es "trabajo" y no es probable que sea el objetivo de OP, se dejará de lado.

Normalmente es b) que se utiliza para "imprimir un valor double con precisión total". Algunas aplicaciones pueden preferir a) error al no proporcionar demasiada información.

Con .scientific , .precision() establece el número de dígitos para imprimir después del punto decimal, por lo que se 1 + .precision() dígitos. El código necesita max_digits10 dígitos totales, por .precision() se llama a .precision() con un max_digits10 - 1 .

typedef std::numeric_limits< double > dbl; std::cout.precision(dbl::max_digits10 - 1); std::cout << std::scientific << exp (-100) << ''/n''; std::cout << std::scientific << exp (+100) << ''/n''; // Typical output 3.7200759760208361e-44 2.6881171418161356e+43

C similar pregunta


Aquí es cómo mostrar un doble con total precisión:

double d = 100.0000000000005; int precision = std::numeric_limits<double>::max_digits10; std::cout << std::setprecision(precision) << d << std::endl;

Esto muestra:

100.0000000000005


max_digits10 es el número de dígitos que son necesarios para representar de forma única todos los valores dobles distintos. max_digits10 representa el número de dígitos antes y después del punto decimal.


No use set_precision (max_digits10) con std :: fixed.
En notación fija, set_precision () establece el número de dígitos solo después del punto decimal. Esto es incorrecto ya que max_digits10 representa el número de dígitos antes y después del punto decimal.

double d = 100.0000000000005; int precision = std::numeric_limits<double>::max_digits10; std::cout << std::fixed << std::setprecision(precision) << d << std::endl;

Esto muestra un resultado incorrecto:

100.00000000000049738


Aquí está lo que yo usaría:

std::cout << std::setprecision (std::numeric_limits<double>::digits10 + 1) << 3.14159265358979 << std::endl;

Básicamente, el paquete de límites tiene rasgos para todos los tipos de compilación.
Uno de los rasgos para los números de punto flotante (float / double / long double) es el atributo dígitos10. Esto define la precisión (olvido la terminología exacta) de un número de punto flotante en la base 10.

Consulte: http://www.cplusplus.com/reference/std/limits/numeric_limits.html
Para detalles sobre otros atributos.


Con ostream :: precision (int)

cout.precision( numeric_limits<double>::digits10 + 1); cout << M_PI << ", " << M_E << endl;

rendirá

3.141592653589793, 2.718281828459045

Por qué tiene que decir "+1" No tengo idea, pero el dígito adicional que obtiene es correcto.


El camino de los iostreams es un poco torpe. Prefiero usar boost::lexical_cast porque calcula la precisión correcta para mí. Y es rápido , también.

#include <string> #include <boost/lexical_cast.hpp> using boost::lexical_cast; using std::string; double d = 3.14159265358979; cout << "Pi: " << lexical_cast<string>(d) << endl;

Salida:

Pi: 3.14159265358979


Lo más portátil ...

#include <limits> using std::numeric_limits; ... cout.precision(numeric_limits<double>::digits10 + 1); cout << d;


Por precisión total, asumo que la precisión media es suficiente para mostrar la mejor aproximación al valor deseado, pero debe señalarse que el double se almacena utilizando la representación de base 2 y la base 2 no puede representar algo tan trivial como 1.1 exactamente. La única forma de obtener la precisión total completa del doble real (sin ERROR DE REDONDA DE DESCUENTO) es imprimir los bits binarios (o nybbles hexadecimales). Una forma de hacerlo es escribir el double en una union y luego imprimir el valor entero de los bits.

union { double d; uint64_t u64; } x; x.d = 1.1; std::cout << std::hex << x.u64;

Esto le dará la precisión 100% precisa del doble ... ¡y será completamente ilegible porque los humanos no pueden leer el formato doble IEEE! Wikipedia tiene un buen escrito sobre cómo interpretar los bits binarios.

En C ++ más reciente, puedes hacer

std::cout << std::hexfloat << 1.1;


Puede establecer la precisión directamente en std::cout y usar el especificador de formato std::fixed .

double d = 3.14159265358979; cout.precision(17); cout << "Pi: " << fixed << d << endl;

Puede #include <limits> para obtener la máxima precisión de flotación o doble.

#include <limits> typedef std::numeric_limits< double > dbl; double d = 3.14159265358979; cout.precision(dbl::max_digits10); cout << "Pi: " << d << endl;


Utilice std::setprecision :

std::cout << std::setprecision (15) << 3.14159265358979 << std::endl;


cout es un objeto que tiene un montón de métodos a los que puede llamar para cambiar la precisión y el formato de las cosas impresas.

Hay una operación setprecision (...), pero también puede configurar otras cosas como el ancho de impresión, etc.

Busque cout en la referencia de su IDE.


printf("%.12f", M_PI);

% .12f significa punto flotante, con una precisión de 12 dígitos.