Pregunta

Tengo una constante que me he fijado ya sea como const o no-const long double. Es más largo (40 dígitos) que la precisión de un long double en mi prueba de estación de trabajo (19 dígitos).

Al imprimir a cabo, ya no aparece a los 19 dígitos de precisión, pero a los 16 años.

Este es el código que estoy probando:

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

int main ()
{
    const long double constLog2 = 0.6931471805599453094172321214581765680755;
    long double log2 = 0.6931471805599453094172321214581765680755;    

    std::cout << std::numeric_limits<long double>::digits10 + 1 << std::endl;
    std::cout << "const via cout: " << std::setprecision(19) << constLog2 << std::endl;
    std::cout << "non-const via cout: " << std::setprecision(19) << log2 << std::endl;
    std::fprintf(stdout, "const via printf: %.19Lf\n", constLog2);
    std::fprintf(stdout, "non-const via printf: %.19Lf\n", log2);

    return 0;
}

Compilar:

$ g++ -Wall precisionTest.cpp

Salida:

$ ./a.out
19
const via cout: 0.6931471805599452862
non-const via cout: 0.6931471805599452862
const via printf: 0.6931471805599452862
non-const via printf: 0.6931471805599452862

Yo esperaría 0.6931471805599453094 pero en lugar de obtener 0.6931471805599452862.

¿Hay una razón por la que los 19 dígitos de precisión se cortan a 16 dígitos?

Aquí está mi entorno:

$ gcc --version
i686-apple-darwin9-g++-4.0.1 (GCC) 4.0.1 (Apple Inc. build 5490)

Estoy viendo el mismo problema con otras versiones de gcc, por ejemplo:.

$ gcc --version
g++ (GCC) 3.4.6 20060404 (Red Hat 3.4.6-10)

Puedo mirar en NTL u otras bibliotecas, pero tengo curiosidad por lo que está causando esto. Gracias por su comprensión.

¿Fue útil?

Solución

Me sale este resultado:

19
const via cout: 0.6931471805599453094
non-const via cout: 0.6931471805599453094
const via printf: 0.6931471805599453094
non-const via printf: 0.6931471805599453094

Pero estoy usando literales dobles largos en lugar de literales dobles:

const long double constLog2 = 0.6931471805599453094172321214581765680755L;
long double log2 = 0.6931471805599453094172321214581765680755L;    

Otros consejos

Hay algunos problemas sutiles relacionados con las plataformas de hardware y compilar las opciones que podrían ser de interés:

Estas opciones `-m' se definen para el i386 y x86-64 familia de ordenadores:

  

-m96bit-largo doble

     

-m128bit-largo doble

     

Estos conmutadores controlan el tamaño de tipo largo doble.   La interfaz de aplicación binaria i386   especifica el tamaño sea de 96 bits, por lo   -m96bit-largo es el doble defecto en el modo de 32 bits. arquitecturas modernas   (Pentium y posteriores) preferirían larga   doble a estar alineadas a un 8 o 16   límite de byte. En matrices o estructuras   conforme a la ABI, esto no haría   ser posible. Así que especifica una   -m128bit-largo doble alineará largo doble a un límite de 16 bytes por   el relleno de la larga doble con una   adicional cero 32 bits.

     

En el compilador x86-64,   -m128bit-largo doble es la opción por defecto como su ABI especifica que a largo   doble es para ser alineado en 16 byte   Perímetro.

     

Tenga en cuenta que ninguna de estas opciones   permitir a cualquier precisión adicional sobre el   estándar x87 de 80 bits por un largo   doble.

     

Advertencia: Si anula el valor predeterminado   valor por su objetivo ABI, la   estructuras y matrices que contienen largo   las variables dobles cambiarán su   tamaño, así como la función que llama   Convención para la función de dar largos   doble se modificará. De ahí que   no será compatible a nivel binario con   matrices o estructuras en código compilado   sin que el interruptor.

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