2009-04-14 12 views
14

Qual è il significato preciso di numeric_limits :: digits10? Alcune altre questioni correlate a StackOverflow mi ha fatto pensare è la massima precisione di un doppio, maQual è il significato di numeric_limits <double> :: digit10

  • il seguente prototipo inizia a lavorare (successo è vero) quando la precisione è maggiore che 17 (== 2 + numeric_limits :: cifre10)
  • Con STLPort, readDouble == infinity alla fine; con STL di microsoft, readDouble == 0.0.
  • Questo prototipo ha qualche significato :)?

Ecco il prototipo:

#include <float.h> 
#include <limits> 
#include <math.h> 
#include <iostream> 
#include <iomanip> 
#include <sstream> 
#include <string> 
int main(int argc, const char* argv[]) { 
    std::ostringstream os; 
    //int digit10=std::numeric_limits<double>::digits10; // ==15 
    //int digit=std::numeric_limits<double>::digits; // ==53 
    os << std::setprecision(17); 
    os << DBL_MAX; 
    std::cout << os.str(); 
    std::stringbuf sb(os.str()); 
    std::istream is(&sb); 
    double readDouble=0.0; 
    is >> readDouble; 
    bool success = fabs(DBL_MAX-readDouble)<0.1; 
} 
+0

correlati: [precisione decimale di carri] (http://stackoverflow.com/questions/3310276/decimal-precision-of-floats) e [È 6 o 7.22?] (ht tp: //stackoverflow.com/q/30688422/183120). – legends2k

risposta

8

numeric_limits :: digits10 specifica il numero di cifre decimali a sinistra del punto decimale si può rappresentare senza perdita di precisione. Ogni tipo avrà un diverso numero di valori decimali rappresentabili.

+0

non significa che il numero può contenere 15 cifre dopo il decimale se non c'è alcun numero tranne 0 prima del punto di radix? – Guillaume07

+0

Questa risposta non è corretta. Vedi [qui] (http://stackoverflow.com/a/13103444/183120). – legends2k

6

Il "53" è la larghezza di bit del significand che il tipo (doppio) trattiene. Il "15" è il numero di decimale cifre che possono essere rappresentate in modo sicuro con quel tipo di precisione.

14

numeric_limits::digits10 è il numero di cifre decimali che può essere trattenuto senza perdita.

Ad esempio numeric_limits<unsigned char>::digits10 è 2. Ciò significa che un char senza segno può contenere 0..99 senza perdita. Se erano 3 poteva contenere 0..999, ma come tutti sappiamo può contenere solo 0,25.

This manual page ha una lista di numeri in virgola mobile, che (quando abbreviato) mostra che

cout << numeric_limits<float>::digits10 <<endl; 
float f = (float)99999999; // 8 digits 
cout.precision (10); 
cout << "The float is; " << f << endl; 

stampe

6 
The float is; 100000000 
+0

Perché ci sono 8 cifre invece di 7 nell'esempio flottante, perché avrebbe potuto essere sufficiente per mostrare il problema? C'è un'altra ragione dietro a questo? – Guillaume07

+1

@ Guillaume07 Per quanto posso dire, tutti i 7 numeri * interi * sopravvivono alla conversione "double-> float-> double" intatta. Il numero intero più piccolo che non riesce è 16777217, ovvero 8 cifre. Una spiegazione del perché numeric_limits :: digits10 è 6 può essere trovato qui http://stackoverflow.com/questions/3310276/decimal-precision-of-floats –

6

Vedi questo articolo molto leggibile: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2005.pdf

Sebbene DBL_MAX (= std :: numeric_limits :: digits10 = 15 cifre) è il numero minimo garantito di cifre per un doubl e, il valore DBL_MAXDIG10 (= 17 cifre) proposta nel documento ha le proprietà utili:

  • di essere il numero minimo di cifre necessarie per sopravvivere un andata e ritorno a forma di stringa e indietro e ottenere lo stesso doppia alla fine.

  • Di essere il numero minimo di cifre necessarie per convertire il doppio in forma di stringa e mostrare stringhe diverse ogni volta che si ottiene (A! = B) nel codice. Con 16 o meno cifre, è possibile ottenere i doppi che non sono uguali nel codice, ma quando sono convertiti in forma stringa sono gli stessi (che daranno il caso in cui sono diversi rispetto al codice, ma un file di registro li mostrerà come identici - molto confusi e difficili da debugare!)

Quando si confrontano i valori (ad esempio rivedendo manualmente da diff'ing due file di log) dobbiamo ricordare che le cifre 1-15 sono sempre validi, ma le differenze nel 16 ° e 17 cifre MAGGIO essere spazzatura.

2

digits10 è per la conversione: stringa → → doppia stringa
max_digits10 è per la conversione: doppia stringa → → doppia

Nel programma, si utilizza la conversione (stringa doppia → → doppia). È necessario utilizzare max_digits10 anziché digits10.


Per maggiori dettagli su digits10 e max_digits10, si può leggere: