2

No logro definir la precisión de un double en C++. Por ejemplo, si el input es 14049.30493 entonces espero como ouput 14049.304930000.

Con mi código :

#include <iostream>
#include <cstdio>
using namespace std;

int main() {
    double d;
    scanf("%lf", &d);
    printf("%lf", d);
    return 0;
}

obtengo el valor 14049.304930.

Xam
  • 834
  • 3
  • 13
  • 21
Revolucion for Monica
  • 4,154
  • 4
  • 28
  • 80

4 Answers4

4

No puedes definir la precisión de un double, su precisión viene dada por cómo esté implementado. C++ sigue la implementación IEEE-754 que dispone de diferentes formatos; el formato de número de coma flotante que se use dependerá de la arquitectura de la máquina en que se ejecute tu programa. Los tipos de datos de coma flotante de C++ son:

  • float: Precisión simple. Habitualmente son un tipo de 32 bits de ancho que sigue el IEEE-754 de 32 bits.
  • double - Precisión doble. Habitualmente son un tipo de 64 bits de ancho que sigue el IEEE-754 de 64 bits.
  • long double - Precisión extendida. Habitualmente son un tipo de 80 bits en arquitecturas de 32 y 64 bits. No necesariamente sigue el IEEE-754.

No quieres cambiar la precisión de double (porque eso no se puede cambiar), quieres cambiar los decimales que muestra por pantalla un valor de ese tipo. Para eso necesitarás la cabecera <iomanip> que ofrece una utilidad para manipular la precisión que se usará para mostrar números por pantalla: el modificador std::setprecision:

double d = 1.0000001;
std::cout << d << '\n';

El código anterior muestra:

1

Porque la precisión que se usa por defecto para mostrar datos no considera relevante el 0.0000001, pero si indicamos una precisión de 8 dígitos:

double d = 1.0000001;
std::cout << std::setprecision(8) << d << '\n';

El código anterior muestra:

1.0000001

Hay que tener en cuenta que esta precisión usa también la parte entera del número, este código:

double d = 1111111.0000001;
std::cout << std::setprecision(8) << d << '\n';

Muestra:

1111111

Si queremos usar la máxima precisión posible para mostrar un dato determinado, podemos apoyarnos en la cabecera <limits> que ofrece una utilidad para saber cuál es la máxima cantidad de dígitos que un tipo de datos puede mostrar en base 10: la función std::numeric_limits::digits10.

Por lo tanto este código:

double d = 1111111.0000001;
std::cout << std::setprecision(std::numeric_limits<double>::digits10 + 1) << d << '\n';

Muestra:

1111111.0000001

Pero si tu número no tiene valores significativos después de un dígito determinado, no te los mostrará, para ello necesitas el modificador std::setw, que te permite indicar cuál será el ancho al mostrar datos, deberás combinarlo con std::left (para indicar que el dato estará a la izquierda del relleno) y std::setfill('0') para indicar que quieres rellenar con el caracter 0. Así que si éste es tu código:

#include <iostream>
#include <iomanip>
#include <limits>

int main() {
    constexpr auto precision = std::numeric_limits<double>::digits10 + 1;
    double d;
    std::cin >> d;
    std::cout << std::setprecision(precision)
              << std::setw(precision)
              << std::setfill('0')
              << std::left
              << d << '\n';
    return 0;
}

Si introduces 14049.30493 verás por pantalla:

14049.3049300000

Pero como puedes ver, es muy complicado y poco práctico, es más sencillo usar std::fixed de la cabecera <ios>, si tienes este código:

double d = 14049.30493;
std::cout << std::setprecision(std::numeric_limits<double>::digits10 + 1)
          << std::fixed
          << d << '\n';

Se mostrará (posiblemente):

14049.3049300000002404

Para saber por qué el programa se está inventando decimales lee este hilo.

PaperBirdMaster
  • 44,474
  • 6
  • 44
  • 82
1
#include <cmath>
#include <cstdio>
using namespace std;

int main()
{
  double a = 14049.30493;
  double  intpart;
  double fractpart = modf (a, &intpart);
  fractpart  = roundf(fractpart * 100000.0)/100000.0; 
  double b = intpart + fractpart;
  printf("%.9lf", b);
}

Salida: 14049.304930000

Darwin Gonzalez
  • 407
  • 2
  • 9
  • Muchas gracias ! Y sabe como definir la precisión cuando tengo dos figuras, una en el otro y el otro doble, siempre con tanta precisión en el doble? – Revolucion for Monica May 17 '18 at 09:54
  • @Marine1 no entiendo muy bien tu pregunta. Recuerda no formular preguntas en los comentarios, crea otra nueva pregunta explicando esa nueva duda y no dudaremos en ayudarte. Buen día – Darwin Gonzalez May 17 '18 at 09:58
0

La respuesta de Paula no pasa todo el caso de prueba. Intenté esto gracias al comentario de quetonix :

#include <iostream>
using std::cin;
using std::cout;
using std::endl;
using std::fixed;

int main() {
    // Complete the code.
    int a; long b; char c; float d; double e;
    cin>>e;
    cout.precision(9);
    cout<<fixed<<e<<endl;
    return 0;
}

No sé para usted pero a mi me parece mas simple

Revolucion for Monica
  • 4,154
  • 4
  • 28
  • 80
-1

Utiliza la libreria iomanip para fijar la precisión en el formato de salida, en combinación con setfixed.

Este ejemplo es sacado de la documentación de la libreria (aqui):

// setprecision example
#include <iostream>     // std::cout, std::fixed
#include <iomanip>      // std::setprecision

int main () {
  double f =3.14159;
  std::cout << std::setprecision(5) << f << '\n';
  std::cout << std::setprecision(9) << f << '\n';
  std::cout << std::fixed;
  std::cout << std::setprecision(5) << f << '\n';
  std::cout << std::setprecision(9) << f << '\n';
  return 0;
}

La salida es:

3.1416
3.14159
3.14159
3.141590000

Espero que te sirva, Saludos.

David
  • 1,191
  • 1
  • 6
  • 13
  • He dicho que lo he sacado de la documentación de la libreria. Tal y como dices, no he puesto la fuente. Edito. Gracias – David May 17 '18 at 10:47
  • Pero queda mejor si pones el enlace... porque webs de documentación hay unas cuantas... – eferion May 17 '18 at 10:48