2015-02-15 10 views
5

Mi sono interessato di recente alla programmazione in C++, perché voglio approfondire la comprensione del modo in cui i computer funzionano e gestiscono le istruzioni. Ho pensato di provare i tipi di dati, ma io in realtà non capire cosa sta succedendo con la mia uscita ...C'è qualcosa di sbagliato nel modo in cui sto usando un lungo doppio?

#include <iostream> 
#include <iomanip> 

using namespace std; 

int main() { 

    float fValue = 123.456789; 
    cout << setprecision(20) << fixed << fValue << endl; 
    cout << "Size of float: " << sizeof(float) << endl; 

    double dValue = 123.456789; 
    cout << setprecision(20) << fixed << dValue << endl; 
    cout << "Size of double: " << sizeof(double) << endl; 

    long double lValue = 123.456789; 
    cout << setprecision(20) << fixed << lValue << endl; 
    cout << "Size of long double: " << sizeof(long double) << endl; 

    return 0; 
} 

L'uscita mi aspettavo sarebbe qualcosa di simile:

123.45678710937500000000 
Size of float: 4 
123.45678900000000000000 
Size of double: 8 
123.45678900000000000000 
Size of long double: 16 

Questo è la mia produzione attuale:

123.45678710937500000000 
Size of float: 4 
123.45678900000000000000 
Size of double: 8 
-6518427077408613100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.00000000000000000000 
Size of long double: 12 

Qualsiasi idea su quello che è successo sarebbe molto apprezzata, grazie!

Edit:

System: 
Windows 10 Pro Technical Preview 
64-bit Operating System, x64-based processor 
Eclipse CDT 8.5 

MinGW Installation

+1

Impossibile riprodurre. Che compilatore stai usando? –

+4

La dimensione di 'long double' varia a seconda del compilatore e dell'hardware. Le taglie 8, 12 e 16 sono note. Quello che vedi come una misura è perfettamente ragionevole, anche se non era quello che ti aspettavi. L'output formattato non è così ragionevole, però. –

+0

FWIW (che è di circa niente), esegue il codice su Mac OS X 10.10.2 con GCC 4.9.1 rendimenti: '123,45678710937500000000 Superficie float: 4 123,45678900000000055570 Dimensioni di doppia: 8 123,45678900000000055570 Superficie long double: 16'. Aggiungendo il suffisso 'F' al valore' float' e il suffisso 'L' al valore' long double' non fa alcuna differenza per l'output 'float' o' double', ma cambia l'output 'long double' a:' 123.45678900000000000059 Dimensioni del doppio lungo: 16', che mostra una precisione migliore. –

risposta

6

Dal patch that fixed this in earlier versions:

MinGW utilizza la DLL runtime msvcrt.dll Microsoft. Qui giace un problema: mentre gcc crea 80 bit di lunghezza doppia, il runtime MS accetta solo doppi a 64 bit.

Questo bug mi succede quando uso 4.8.1 Revisione 4 da MinGW-get (la versione più recente che offre), ma non quando io uso 4.8.1 revisione 5.

Così si sono non usare il doppio lungo sbagliato (anche se ci sarebbe una maggiore precisione per fare long double lValue = 123.456789L per assicurarsi che non ci vuole 123.456789 come un doppio, quindi lanciarlo su un lungo doppio).

Il modo più semplice per risolvere questo problema è semplicemente cambiare la versione di MinGW che si sta utilizzando a 4.9 o 4.7, a seconda di cosa è necessario (è possibile ottenere 4.9 here).

Se siete disposti utilizzare invece printf, è possibile cambiare a printf("%Lf", ...), e:

  • aggiunge il -posix flag quando si compila con g ++
  • aggiungere #define __USE_MINGW_ANSI_STDIO 1 prima #include <cstdio> (trovato utile questa dal origional patch)

Infine, si può anche solo lanciare un double ogni volta che si tenta di stampare il long double (v'è una certa perdita di precisione, ma non dovrebbe importare quando si stampano solo numeri).

Per ulteriori informazioni, è anche possibile consultare my blog post on this issue.

Aggiornamento: Se si desidera continuare a utilizzare Mingw 4.8, è possibile anche solo download una diversa distribuzione di Mignw, che non ha avuto questo problema per me.

Problemi correlati