La precisione della lunga doppia uscita non è corretta. Che cosa potrebbe essere sbagliato?

StackOverflow https://stackoverflow.com/questions/684112

Domanda

Ho un long double costante che sto installando sia come const o no-const. E 'più lungo (40 cifre) che la precisione di un long double sulla mia workstation di prova (19 cifre).

Quando stampo fuori, non è più visualizzata a 19 cifre di precisione, ma a 16 anni.

Ecco il codice che sto testando:

#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;
}

Compila:

$ g++ -Wall precisionTest.cpp

Output:

$ ./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

mi aspetterei 0.6931471805599453094 ma invece ottenere 0.6931471805599452862.

C'è un motivo che i 19 cifre di precisione sono tagliati a 16 cifre?

Qui è il mio ambiente:

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

sto vedendo lo stesso problema con altre versioni di gcc, per esempio:.

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

posso guardare in NTL o altre librerie, ma sono curioso di ciò che sta causando questo. Grazie per la vostra comprensione.

È stato utile?

Soluzione

ottengo questo output:

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

Ma sto usando lunghi letterali matrimoniali invece di doppi letterali:

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

Altri suggerimenti

Ci sono alcune questioni relative alla sottili piattaforme hardware e compilare le opzioni che potrebbero essere di interesse:

Queste opzioni `-m' sono definiti per l'i386 e x86-64 famiglia di computer:

  

-m96bit-lungo doppio

     

-m128bit-lungo doppio

     

Questi interruttori controllano la dimensione di tipo lungo doppio.   L'interfaccia binaria applicazione i386   Specifica la dimensione sia 96 bit, così   --M96bit-lungo doppio è l'impostazione predefinita in modalità a 32 bit. architetture moderne   (Pentium e successivi) preferirebbero lunga   doppio per essere allineato con un 8 o 16   limite di byte. In array o strutture   conforme al ABI, questo non sarebbe   Essere possibile. Quindi, specificando un   --M128bit-lungo doppio allineerà long double a un limite di 16 byte per   imbottitura la lunga doppia con un   ulteriori 32 bit a zero.

     

Nel compilatore x86-64,   --M128bit-long double è la scelta di default come il suo ABI specifica che a lungo   doppio deve essere allineata a 16 byte   confine.

     

Si noti che nessuna di queste opzioni   permettere a qualsiasi precisione in più oltre il   norma x87 80 bit per un lungo   Doppio.

     

Attenzione: se si ignora il valore di default   valore per il vostro obiettivo di ABI, il   strutture e matrici contenenti lungo   variabili doppie cambieranno il loro   dimensioni così come la funzione di chiamata   convenzione per la funzione presa lungo   doppia verrà modificato. Perciò essi   non sarà compatibile con binario   array o strutture in codice compilato   senza che l'interruttore.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top