Comment imprimer une doublevaleur en toute précision avec cout?
Utiliser hexfloatou
utiliser scientificet définir la précision
std::cout.precision(std::numeric_limits<double>::max_digits10 - 1);
std::cout << std::scientific << 1.0/7.0 << '\n';
// C++11 Typical output
1.4285714285714285e-01
Trop de réponses ne concernent qu'une des 1) base 2) disposition fixe / scientifique ou 3) précision. Trop de réponses avec précision ne fournissent pas la valeur appropriée requise. D'où cette réponse à une vieille question.
- Quelle base?
A doubleest certainement codé en utilisant la base 2. Une approche directe avec C ++ 11 consiste à imprimer en utilisant std::hexfloat.
Si une sortie non décimale est acceptable, nous avons terminé.
std::cout << "hexfloat: " << std::hexfloat << exp (-100) << '\n';
std::cout << "hexfloat: " << std::hexfloat << exp (+100) << '\n';
// output
hexfloat: 0x1.a8c1f14e2af5dp-145
hexfloat: 0x1.3494a9b171bf5p+144
- Sinon:
fixedou scientific?
A doubleest un type à virgule flottante , pas un point fixe .
Ne l' utilisez passtd::fixed car cela ne s'imprime pas doublecomme autre chose 0.000...000. Pour les grands double, il imprime de nombreux chiffres, peut-être des centaines d'informations douteuses.
std::cout << "std::fixed: " << std::fixed << exp (-100) << '\n';
std::cout << "std::fixed: " << std::fixed << exp (+100) << '\n';
// output
std::fixed: 0.000000
std::fixed: 26881171418161356094253400435962903554686976.000000
Pour imprimer avec une précision totale, utilisez d'abord std::scientificqui "écrit des valeurs à virgule flottante en notation scientifique". Notez la valeur par défaut de 6 chiffres après la virgule décimale, une quantité insuffisante, est gérée au point suivant.
std::cout << "std::scientific: " << std::scientific << exp (-100) << '\n';
std::cout << "std::scientific: " << std::scientific << exp (+100) << '\n';
// output
std::scientific: 3.720076e-44
std::scientific: 2.688117e+43
- Quelle précision (combien de chiffres au total)?
Un doublecodé à l'aide de la base binaire 2 code la même précision entre différentes puissances de 2. Il s'agit souvent de 53 bits.
[1.0 ... 2.0) il y en a 2 53 différents double,
[2.0 ... 4.0) il y en a 2 53 différents double,
[4.0 ... 8.0) il y en a 2 53 différents double,
[8.0 ... 10.0) il y en a 2 / 8 * 2 53 différents double.
Pourtant , si code imprime en décimal avec Nchiffres significatifs, le nombre de combinaisons [1.0 ... 10.0) est 9/10 * 10 N .
Quelle que soit la N(précision) choisie, il n'y aura pas de correspondance un à un entre doublele texte décimal et le texte décimal. Si un fixe Nest choisi, il sera parfois légèrement plus ou moins que vraiment nécessaire pour certaines doublevaleurs. Nous pourrions commettre des erreurs sur trop peu ( a)ci-dessous) ou trop ( b)ci-dessous).
3 candidat N:
a) Utilisez un Ntel lors de la conversion de texte-texte, doublenous arrivons au même texte pour tous double.
std::cout << dbl::digits10 << '\n';
// Typical output
15
b) Utilisez un Nso lors de la conversion de double-text- doublenous arrivons au même doublepour tous double.
// C++11
std::cout << dbl::max_digits10 << '\n';
// Typical output
17
Lorsque max_digits10n'est pas disponible, notez qu'en raison des attributs base 2 et base 10 digits10 + 2 <= max_digits10 <= digits10 + 3, nous pouvons utiliser digits10 + 3pour garantir que suffisamment de chiffres décimaux sont imprimés.
c) Utilisez un Nqui varie avec la valeur.
Cela peut être utile lorsque le code souhaite afficher un texte minimal ( N == 1) ou la valeur exacte de a double( N == 1000-ishdans le cas de denorm_min). Pourtant, comme il s'agit de «travail» et peu probable de l'objectif du PO, il sera mis de côté.
C'est généralement b) qui est utilisé pour "imprimer une doublevaleur avec une précision totale". Certaines applications peuvent préférer a) à l'erreur de ne pas fournir trop d'informations.
Avec .scientific, .precision()définit le nombre de chiffres à imprimer après la virgule décimale pour que les 1 + .precision()chiffres soient imprimés. Le code a besoin d'un max_digits10nombre total de chiffres et .precision()est donc appelé avec un max_digits10 - 1.
typedef std::numeric_limits< double > dbl;
std::cout.precision(dbl::max_digits10 - 1);
std::cout << std::scientific << exp (-100) << '\n';
std::cout << std::scientific << exp (+100) << '\n';
// Typical output
3.7200759760208361e-44
2.6881171418161356e+43
//1234567890123456 17 total digits
Question C similaire
fixed? Avecdouble h = 6.62606957e-34;,fixedme donne0.000000000000000etscientificsort6.626069570000000e-34.