J'ai lu des recommandations pour utiliser les valeurs "FLT_MIN" et "FLT_MAX" pour float. Chaque fois que je fais cela, les blocs de code me disent
max: 3.40282e + 038 min: 1.17549e-038
Ne sachant pas ce que cela signifiait, j'ai essayé d'obtenir de vraies valeurs et
max: 47.2498237715 min: -34.8045265148
... mais cela ne clarifie pas les choses.
Voici un extrait de mon code
char c; // reserve: 1 byte, store 1 character (-128 to 127)
int i; // reserve: 4 bytes, store -2147483648 to 2147483657
short int s; // reserve: 2 bytes, store -32768 to 32767
float f; // reserve: 4 bytes, store ?? - ?? (? digits)
double d; // reserve: 8 bytes, store ?? - ?? (? digits)
unsigned int u; //reserve: r bytes store 0 to 4294967295
c = 'c';
cout << c <<" lives at " << &c <<endl;
i = 40000;
cout << i <<" lives at " << &i <<endl;
s = 100;
cout << s <<" lives at " << &s <<endl;
f = 10.1;
cout << f <<" lives at " << &f <<endl;
d = 10.102;
cout << d <<" lives at " << &d <<endl;
u = 1723;
cout << u <<" lives at " << &u <<endl;
Dans l'extrait, nous pouvons clairement voir les valeurs min-max d'un short int, par exemple à -32768 - 32767. Ce sont des valeurs compréhensibles appropriées, mais pour float et int, les valeurs réelles ne sont pas claires.
La classe std::numerics_limits
Dans l'en-tête <limits>
Fournit des informations sur les caractéristiques des types numériques.
Pour un type à virgule flottante T
, voici les valeurs les plus grandes et les moins représentables dans le type, dans divers sens de "plus grand" et "moins". J'inclus également les valeurs du type binaire 64 bits IEEE 754 commun, appelé double
dans cette réponse. Ce sont en ordre décroissant:
std::numeric_limits<T>::infinity()
est la plus grande valeur représentable si T
prend en charge l'infini. C'est, bien sûr, l'infini. La prise en charge de l'infini par le type T
est indiquée par std::numeric_limits<T>::has_infinity
.
std::numeric_limits<T>::max()
est la plus grande valeur finie. Pour double
, c'est 21024-2971, environ 1,79769 • 10308.
std::numeric_limits<T>::min()
est la plus petite valeur normale positive. Les formats à virgule flottante ont souvent un intervalle où l'exposant ne peut pas devenir plus petit, mais la significande (partie fraction du nombre) est autorisée à devenir plus petite jusqu'à ce qu'elle atteigne zéro. Cela se fait au détriment de la précision, mais présente certaines propriétés souhaitables de calcul mathématique. min()
est le point de départ de cette perte de précision. Pour double
, c'est 2−1022, environ 2,22507 • 10−308.
std::numeric_limits<T>::denorm_min()
est la plus petite valeur positive. Dans les types qui ont des valeurs sous-normales, elle est sous-normale. Sinon, il est égal à std::numeric_limits<T>::min()
. Pour double
, c'est 2−1074, environ 4,94066 • 10−324.
std::numeric_limits<T>::lowest()
est la valeur la moins finie. Il s'agit généralement d'un nombre négatif de grande ampleur. Pour double
, c'est - (21024-2971), environ −1,79769 • 10308.
Si std::numeric_limits<T>::has_infinity
Et std::numeric_limits<T>::is_signed
Sont vrais, alors -std::numeric_limits<T>::infinity()
est la plus petite valeur. C'est, bien sûr, l'infini négatif.
Une autre caractéristique qui pourrait vous intéresser est:
std::numeric_limits<T>::digits10
Est le plus grand nombre de chiffres décimaux, de sorte que la conversion de n'importe quel nombre décimal avec autant de chiffres en T
, puis la reconversion au même nombre de chiffres décimaux produira le nombre d'origine. Pour double
, c'est 15.Tout se trouve dans numeric_limits.
Mais [~ # ~] méfiez-vous [~ # ~]
Pour une raison que je ne connais pas, std::numeric_limits<float>:min()
ne retourne pas le flottant minimum. Au lieu de cela, il renvoie le plus petit flottant positif représenté sous une forme normalisée. Pour obtenir le minimum, utilisez std::numeric_limits<float>::lowest()
. Je ne plaisante pas. De même pour les autres types à virgule flottante, c'est-à-dire double
et long double
.
Bien. En utilisant ce que j'ai appris d'ici (merci à tous) et les autres parties du Web, j'ai écrit un petit résumé des deux, au cas où je rencontrerais un autre problème comme celui-ci.
En C++, il existe deux façons de représenter/stocker des valeurs décimales.
-179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368,0000000000000000 double le plus bas
179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368,0000000000000000 Double max
La précision de Float lui permet de stocker une valeur allant jusqu'à 9 chiffres (7 chiffres réels, +2 de la conversion décimale en binaire)
Double, comme son nom l'indique, peut stocker deux fois plus de cul que de flotteur. Il peut stocker jusqu'à 17 chiffres. (15 chiffres réels, +2 de la conversion décimale en binaire)
par exemple.
float x = 1.426;
double y = 8.739437;
En raison d'un flotteur pouvant transporter 7 décimales réelles , et un double capable de porter 15 réels décimales, lors des calculs, les imprimer, une méthode appropriée doit être utilisée.
par exemple
typedef std::numeric_limits<double> dbl;
cout.precision(dbl::max_digits10-2); // sets the precision to the *proper* amount of digits.
cout << dbl::max_digits10 <<endl; // prints 17.
double x = 12345678.312;
double a = 12345678.244;
// these calculations won't perform correctly be printed correctly without setting the precision.
cout << endl << x+a <<endl;
exemple 2:
typedef std::numeric_limits< float> flt;
cout.precision(flt::max_digits10-2);
cout << flt::max_digits10 <<endl;
float x = 54.122111;
float a = 11.323111;
cout << endl << x+a <<endl; /* without setting precison this outputs a different value, as well as making sure we're *limited* to 7 digits. If we were to enter another digit before the decimal point, the digits on the right would be one less, as there can only be 7. Doubles work in the same way */
Quelle est la précision de cette description? Peut-il être utilisé comme standard lorsqu'il est condusé?
En C++, vous pouvez utiliser le std::numeric_limits
classe pour obtenir ce type d'informations.
Si has_infinity
est true
(ce qui est le cas pour pratiquement toutes les plateformes de nos jours), alors vous pouvez utiliser infinity
pour obtenir la valeur qui est supérieure ou égale à toutes les autres valeurs (sauf NaN). Sa négation donnera un infini négatif, et sera inférieure ou égale à toutes les autres valeurs (sauf NaN à nouveau).
Si vous voulez des valeurs finies, vous pouvez utiliser max
, qui sera supérieur ou égal à toutes les autres valeurs finies, et lowest
=, qui est inférieur ou égal à toutes les autres valeurs finies.
Quelque peu confus, min
vous donne en fait la plus petite valeur normalisée positive, qui est complètement désynchronisée avec ce qu'elle donne avec les types entiers (merci @JiveDadson de l'avoir signalé).