Pregunta

Entonces obtuve la respuesta a mi última pregunta (No sé por qué no pensé en eso).Estaba imprimiendo un double usando cout eso se redondeó cuando no lo esperaba.¿Cómo puedo hacer? cout imprimir un double usando total precisión?

¿Fue útil?

Solución

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

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

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

#include <limits>

typedef std::numeric_limits< double > dbl;

double d = 3.14159265358979;
cout.precision(dbl::max_digits10);
cout << "Pi: " << d << endl;

Otros consejos

std::setprecision :

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

Esto es lo que me gustaría utilizar:

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

Básicamente el paquete tiene rasgos límites para toda la estructura en tipos.
Uno de los rasgos de números de punto flotante (float / doble / doble largo) es el atributo digits10. Esto define la precisión (no recuerdo la terminología exacta) de un número de coma flotante en la base 10.

Ver: http://www.cplusplus.com/reference/std/ límites / numeric_limits.html
Para obtener detalles sobre otros atributos.

La forma iostreams es una especie de torpe. Yo prefiero usar boost::lexical_cast porque calcula la precisión adecuada 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

Aquí es cómo mostrar una doble con precisión completa:

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 necesarias para representar de forma única todos los valores dobles distintas. max_digits10 representa el número de dígitos antes y después del punto decimal.


No utilizar set_precision (max_digits10) con std :: fijo.
En notación fija, set_precision () establece el número de dígitos sólo después el punto decimal. Esto es incorrecto como max_digits10 representa el número de dígitos antes y después el 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 resultado incorrecto:

  

100,00000000000049738

Nota: Los archivos de cabecera necesarios

#include <iomanip>
#include <limits>

Por la precisión completa, supongo que quiere decir suficiente precisión como para mostrar la mejor aproximación al valor previsto, pero hay que señalar que double se almacena utilizando de base 2 y la representación de base 2 no puede representar algo tan trivial como 1.1 exactamente. La única manera de conseguir la completamente llena precisión de la actual doble (SIN error de redondeo) es imprimir los bits binarios (o nybbles hexagonales). Una forma de hacer que está escribiendo el double a un 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 exacta del 100% de la doble ... y ser totalmente ilegible porque los seres humanos no pueden leer IEEE formato doble! Wikipedia tiene una buena escritura sobre cómo interpretar los bits binarios.

En reciente C ++, puede hacerlo

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

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

Usar hexfloat o
usar scientific y establecer 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 uno 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. ¿Qué base?

A double ciertamente está codificado usando 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?

A double es un punto flotante tipo, no punto fijo.

Hacer no usar std::fixed ya que eso no se imprime en tamaño pequeño double como cualquier cosa menos 0.000...000.Para grande double, imprime muchos dígitos, tal vez 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, utilice por primera vez 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 trata 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 en total)?

A double codificado usando el binario base 2 codifica la misma precisión entre varias potencias de 2.Suele ser de 53 bits.

[1.0...2.0) hay 253 diferente double,
[2.0...4.0) hay 253 diferente double,
[4.0...8.0) hay 253 diferente double,
[8.0...10.0) hay 2/8 * 253 diferente double.

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 * 10norte.

Lo que N (precisión), no habrá un mapeo uno a uno entre double y texto decimal. si es fijo N se elige, a veces será un poco más o menos de lo realmente necesario para ciertos double valores.Podríamos cometer errores en muy pocos (a) abajo) o demasiados (b) abajo).

3 candidato N:

a) Utilice un N entonces, al convertir de texto-double-texto llegamos al mismo texto para todos double.

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

b) Utilice un N entonces al convertir de double-texto-double llegamos al mismo double para todos 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, nosotros podemos usar digits10 + 3 para asegurar que se impriman suficientes dígitos decimales.

c) Utilice un N eso varía con el valor.

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


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

Con .scientific, .precision() establece el número de dígitos que se imprimirán después del punto decimal, por lo que 1 + .precision() Se imprimen los dígitos.Necesidades de código max_digits10 dígitos totales entonces .precision() se llama 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

Pregunta C similar

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

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

cout es un objeto que tiene un montón de métodos que puede llamar para cambiar la precisión y el formato del material impreso.

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

Busque cout en la referencia de su IDE.

La mayoría portable ...

#include <limits>

using std::numeric_limits;

    ...
    cout.precision(numeric_limits<double>::digits10 + 1);
    cout << d;

Con ostream :: precisión (int)

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

rendirá

3.141592653589793, 2.718281828459045

¿Por qué usted tiene que decir "1" que no tienen ni idea, pero el dígito adicional a salir de ella es correcta.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top