2010-06-15 5 views
4

Je me demandais, combien de temps en nombre de caractères serait le plus long un double imprimé en utilisant fprintf? Ma conjecture est fausse.Largeur maximum d'un double imprimé en C++

Merci d'avance.

+0

Vous devez utiliser% e si vous voulez qu'il soit limité. –

+0

duplicata possible de [Quelle est la longueur maximale en caractères nécessaires pour représenter une double valeur?] (Http://stackoverflow.com/questions/1701055/what-is-the-maximum-length-in-chars-needed-to -represent-any-double-value) –

Répondre

6

Qui sait . La norme ne dit pas combien de chiffres de précision un double fournit autrement que de le dire (3.9.1.8) "fournit au moins autant de précision que le flottant", donc vous n'avez pas vraiment connaître combien de caractères vous aurez besoin à sprintf une valeur arbitraire. Même si vous connaissiez le nombre de chiffres fournis par votre implémentation, il reste la question de la mise en forme exponentielle, etc.

Mais il y a une question beaucoup plus grande ici. Pourquoi diable voulez-vous? Je devine que c'est parce que vous essayez d'écrire quelque chose comme ceci:

double d = ...; 
int MAGIC_NUMBER = ...; 
char buffer[MAGIC_NUMBER]; 
sprintf(buffer, "%f", d); 

C'est une mauvaise façon de le faire, précisément parce que vous ne savez pas comment grand MAGIC_NUMBER devrait être. Vous pouvez choisir quelque chose qui devrait être assez grand, comme 14 ou 128k, mais alors le nombre que vous avez choisi est arbitraire, pas basé sur quoi que ce soit mais devinez qu'il sera assez grand. Les nombres comme MAGIC_NUMBER sont, pas étonnamment, appelés Magic Numbers. Reste loin d'eux. Ils vous feront pleurer un jour. Au lieu de cela, il y a beaucoup de façons de faire ce formatage de chaîne sans avoir à se préoccuper de la taille des tampons, des chiffres de précision, etc., qui vous permettent de vous concentrer sur la programmation. Cours d'eau est un:

#include <sstream> 

double d = ...; 
stringstream ss; 
ss << d; 
string s = ss.str(); 
cout << s; 

... Boost.Format est une autre:

#include <boost\format\format.hpp> 

double d = ... ; 
string s = (boost::format("%1%") % d).str(); 
cout << s; 
+0

En fait, si vous utilisez'% f' , peu importe la précision réelle du 'double', car'% f' l'arrondira toujours à la précision spécifiée dans la chaîne de formatage (la valeur par défaut est 6 si elle est omise). Donc, vous connaissez toujours le nombre de chiffres après la virgule. Et ceux d'avant? Vous pouvez toujours utiliser 'FLT_MAX' (ou' numeric_limits') pour cela. –

8

Douze serait un peu une sous-estimation. Sur ma machine, les résultats suivants dans une longue chaîne de caractères 317:

#include <limits> 
#include <cstdio> 
#include <cstring> 

int main() 
{ 
    double d = -std::numeric_limits<double>::max(); 
    char str[2048] = ""; 

    std::sprintf(str, "%f", d); 

    std::size_t length = std::strlen(str); 
} 

En utilisant %e résultats dans une longue chaîne 14 caractères.

+1

Notez que cela ne reflète * pas * la précision de la valeur double elle-même. –

+0

Au moins * utiliser 'snprintf'. – strager

+0

@strager: Eh bien, même si je n'utiliserais jamais ou ne recommanderiez jamais l'utilisation de 'sprintf' comme ça dans le code de production, pour un exemple rapide ... eh ... –

0

vous pouvez décider par vous-même ..

double a=1.1111111111111111111111111111111111111111111111111; 
printf("%1.15lf\n", a); 
return 0; 

./a.out
1,111111111111111

vous pouvez imprimer plus de 12 caractères ..

2

Son définis dans les limites:

std::cout << std::numeric_limits<double>::digits << "\n"; 
std::cout << std::numeric_limits<double>::digits10 << "\n"; 

Définition:

digits: number of digits (in radix base) in the mantissa 
      Equivalent to FLT_MANT_DIG, DBL_MANT_DIG or LDBL_MANT_DIG. 
digits10: Number of digits (in decimal base) that can be represented without change. 
      Equivalent to FLT_DIG, DBL_DIG or LDBL_DIG for floating types. 

Voir: http://www.cplusplus.com/reference/std/limits/numeric_limits/

Bien sûr, lorsque vous imprimez des données dans un flux, vous pouvez utiliser les manipulateurs de flux pour limiter la taille de la sortie.

+1

Notez que 'digits10' est le nombre de chiffres _of precision_. Un nombre tel que '1.23e + 100' n'a que 3 chiffres de précision, mais s'il est imprimé en entier sans notation exponentielle, il aurait 101 chiffres dans la sortie. Bien sûr, la question ne spécifie pas le format dans lequel le nombre doit être imprimé ... mais si elle est exponentielle, vous devez également tenir compte de l'exposant de taille variable. –

0

Si votre machine utilise des doubles IEEE754 (ce qui est assez répandu maintenant), alors la précision binaire est de 53 bits; L'équivalent décimal est d'environ 15,95 (calculé par conversion logarithmique), de sorte que vous pouvez généralement compter sur 15 chiffres décimaux de précision.

Consultez Double precision floating-point format pour une brève discussion.

Pour une étude beaucoup plus approfondie, l'article canonique est What Every Computer Scientist Should Know About Floating-Point Arithmetic. Il est cité ici chaque fois que des discussions binaires à virgule flottante apparaissent et valent un week-end de lecture attentive.