J'ai donc obtenu la réponse à ma dernière question (je ne sais pas pourquoi je n'y ai pas pensé). J'imprimais une double
utilisation cout
qui a été arrondie quand je ne m'y attendais pas. Comment puis-je faire cout
imprimer une double
utilisation en toute précision?
332
fixed
? Avecdouble h = 6.62606957e-34;
,fixed
me donne0.000000000000000
etscientific
sort6.626069570000000e-34
.cout.precision(numeric_limits<double>::digits10 + 2);
seulement 16 ....max_digits10
pour désigner la même chose. Correction de la réponse pour refléter cela.Utilisation
std::setprecision
:la source
std::setprecision (17)
pour le double, voir les commentaires sur la réponse de @Bill The Lizard.Voici ce que j'utiliserais:
Fondamentalement, le package de limites a des caractéristiques pour tous les types intégrés.
L'un des traits des nombres à virgule flottante (float / double / long double) est l'attribut digits10. Cela définit la précision (j'oublie la terminologie exacte) d'un nombre à virgule flottante en base 10.
Voir: http://www.cplusplus.com/reference/std/limits/numeric_limits.html
Pour plus de détails sur les autres attributs.
la source
std::setprecision()
:#include <iomanip>
std::numeric_limits<double>
au lieu denumberic_limits<double>
1
àstd::numeric_limits<double>::digits10
?max_digits10
place. Regardez ça .max_digits10
, pas arbitrairedigits10+2
. Dans le cas contraire, dans le casfloat
,long double
,boost::multiprecision::float128
cela ne fonctionne pas, car il vous auriez besoin au+3
lieu de+2
.La manière iostreams est un peu maladroite. Je préfère utiliser
boost::lexical_cast
car il calcule la bonne précision pour moi. Et c'est rapide aussi.Production:
la source
Par pleine précision, je suppose que suffisamment de précision pour montrer la meilleure approximation de la valeur prévue, mais il convient de souligner que
double
stocké en utilisant la représentation de base 2 et que la base 2 ne peut pas représenter quelque chose d'aussi trivial1.1
qu'exactement. La seule façon d'obtenir la précision totale du double réel (sans ERREUR ARRÊT ROND) est d'imprimer les bits binaires (ou les octets hexadécimaux). Une façon de procéder consiste à écrire ledouble
dans ununion
, puis à imprimer la valeur entière des bits.Cela vous donnera la précision à 100% du double ... et sera totalement illisible car les humains ne peuvent pas lire le double format IEEE! Wikipedia a une bonne écriture sur la façon d'interpréter les bits binaires.
Dans le C ++ plus récent, vous pouvez faire
la source
Voici comment afficher un double en toute précision:
Cela affiche:
max_digits10 est le nombre de chiffres nécessaires pour représenter de manière unique toutes les valeurs doubles distinctes. max_digits10 représente le nombre de chiffres avant et après le point décimal.
N'utilisez pas set_precision (max_digits10) avec std :: fixed.
En notation fixe, set_precision () définit le nombre de chiffres uniquement après le point décimal. Ceci est incorrect car max_digits10 représente le nombre de chiffres avant et après le point décimal.
Cela affiche un résultat incorrect:
Remarque: fichiers d'en-tête requis
la source
100.0000000000005
n'est pas représenté exactement comme undouble
. (Cela peut sembler être le cas, mais ce n'est pas le cas, car il est normalisé , c'est-à-dire sa représentation binaire). Pour voir cela, essayez:100.0000000000005 - 100
. Nous obtenons4.973799150320701e-13
.Utiliser
hexfloat
ouutiliser
scientific
et définir la précisionTrop 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.
A
double
est certainement codé en utilisant la base 2. Une approche directe avec C ++ 11 consiste à imprimer en utilisantstd::hexfloat
.Si une sortie non décimale est acceptable, nous avons terminé.
fixed
ouscientific
?A
double
est un type à virgule flottante , pas un point fixe .Ne l' utilisez pas
std::fixed
car cela ne s'imprime pasdouble
comme autre chose0.000...000
. Pour les grandsdouble
, il imprime de nombreux chiffres, peut-être des centaines d'informations douteuses.Pour imprimer avec une précision totale, utilisez d'abord
std::scientific
qui "é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.Un
double
codé à 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
N
chiffres 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 entredouble
le texte décimal et le texte décimal. Si un fixeN
est choisi, il sera parfois légèrement plus ou moins que vraiment nécessaire pour certainesdouble
valeurs. Nous pourrions commettre des erreurs sur trop peu (a)
ci-dessous) ou trop (b)
ci-dessous).3 candidat
N
:a) Utilisez un
N
tel lors de la conversion de texte-texte,double
nous arrivons au même texte pour tousdouble
.b) Utilisez un
N
so lors de la conversion dedouble
-text-double
nous arrivons au mêmedouble
pour tousdouble
.Lorsque
max_digits10
n'est pas disponible, notez qu'en raison des attributs base 2 et base 10digits10 + 2 <= max_digits10 <= digits10 + 3
, nous pouvons utiliserdigits10 + 3
pour garantir que suffisamment de chiffres décimaux sont imprimés.c) Utilisez un
N
qui varie avec la valeur.Cela peut être utile lorsque le code souhaite afficher un texte minimal (
N == 1
) ou la valeur exacte de adouble
(N == 1000-ish
dans le cas dedenorm_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
double
valeur 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 les1 + .precision()
chiffres soient imprimés. Le code a besoin d'unmax_digits10
nombre total de chiffres et.precision()
est donc appelé avec unmax_digits10 - 1
.Question C similaire
la source
precision()
définit le nombre de décimales pour le mode scientifique. Sans spécifierscientific
, il définit le nombre total de chiffres, à l'exclusion de l'exposant. Vous pouvez toujours vous retrouver avec une sortie scientifique, en fonction de la valeur de votre numéro, mais vous pouvez également obtenir moins de chiffres que ce que vous avez spécifié. Exemple: lescout.precision(3); cout << 1.7976931348623158e+308; // "1.8e+308"
résultats pourprintf
peuvent être différents. Il faut être conscient des choses confuses.char buf[DBL_DECIMAL_DIG + 3 + 5]; sprintf(buf, "%.*g", DBL_DECIMAL_DIG, d);
les caractères supplémentaires sont pour: signe, virgule décimale, zéro de fin, e [+ | -], 3 chiffres pour l'exposant ( DBL_MAX_10_EXP = 308). Le nombre total de caractères requis est donc de 25.% .12f signifie virgule flottante, avec une précision de 12 chiffres.
la source
Plus facilement ...
la source
Avec ostream :: precision (int)
donnera
Pourquoi vous devez dire "+1" Je n'ai aucune idée, mais le chiffre supplémentaire que vous en retirez est correct.
la source
Cela montrera la valeur jusqu'à deux décimales après le point.
Voir ici: notation à virgule fixe
std :: fixed
std :: setprecision
Si vous connaissez la norme IEEE pour représenter les virgules flottantes, vous savez qu'il est impossible d'afficher des virgules flottantes avec une précision totale hors du champ d'application de la norme , c'est-à-dire que cela se traduira toujours par un arrondi de la valeur réelle.
Vous devez d'abord vérifier si la valeur est dans la portée , si oui, utilisez ensuite:
std :: defaultfloat
C'est également le comportement par défaut de
cout
, ce qui signifie que vous ne l'utilisez pas explicitement.la source