115 votes

Valeur double minimale en C/C++

Existe-t-il un moyen standard et/ou portable de représenter la plus petite valeur négative (par exemple, d'utiliser l'infini négatif) dans un programme C++?

DBL_MIN dans float.h est le plus petit nombre positif.

4 votes

Je vais choisir -DBL_MAX, mais je suis sûr qu'il y a une raison technique pour laquelle ce n'est pas le cas :-)

4 votes

@Neil, non, ce n'est pas comme les entiers en complément à 2

0 votes

Je n'ai encore rien vu dans la norme pour dire que la gamme des types de point flottant doit être symétrique autour de zéro. Mais les constantes dans limits.h et suggèrent que les normes C et C++ s'attendent un peu à ce qu'elles le soient.

154voto

dfa Points 54490

-DBL_MAX en ANSI C, qui est défini dans float.h.

0 votes

Cela semble être le plus standard et portable

0 votes

Voici l'explication de mon -1: qui ou quoi dit que -DBL_MAX est garanti par le langage C ou C++ d'être représentable, sans parler de la valeur minimale représentable? Le fait que la plupart du matériel FP soit conforme à IEEE 754 et utilise cette représentation ne signifie pas que -DBL_MAX est garanti de fonctionner sur n'importe quelle plateforme C conforme à la norme.

0 votes

@j_random_hacker: voir la réponse de fortran ci-dessous.

77voto

fortran Points 26495

Les nombres à virgule flottante (IEEE 754) sont symétriques, donc si vous pouvez représenter la plus grande valeur (DBL_MAX ou numeric_limits::max()), il suffit de préfixer un signe négatif.

Et voici la manière cool:

double f;
(*((uint64_t*)&f))= ~(1LL<<52);

9 votes

+1 Pour avoir souligné la symétrie des nombres en virgule flottante :)

6 votes

Que dire des implémentations C/C++ qui n'utilisent pas les flottants IEEE 754?

0 votes

@onebyone, dites-moi en un qui ne le fait pas... Je pense que vous ne pourrez pas, car tous les compilateurs C/C++ utilisent le format natif du processeur pour les nombres en virgule flottante, et maintenant je ne peux pas penser à un seul FPU qui ne respecte pas la norme IEEE 754 (peut-être dans les temps sombres de l'informatique, quand tout le monde avait ses propres formats maison...)

57voto

rubenvb Points 27271

En C, utilisez

#include 

const double lowest_double = -DBL_MAX;

En C++pre-11, utilisez

#include 

const double lowest_double = -std::numeric_limits::max();

En C++11 et au-delà, utilisez

#include 

constexpr double lowest_double = std::numeric_limits::lowest();

0 votes

La fonction min() n'était-elle pas disponible avant C++11? Ou s'agit-il d'une valeur différente de -max()? en.cppreference.com/w/cpp/types/numeric_limits

7 votes

@Alexis : si vous regardez les trois dernières lignes du tableau sur la page que vous avez liée, vous verrez que min vous donne la plus petite valeur positive en magnitude, et lowest la plus grande valeur négative en magnitude. Oui, c'est terrible. Bienvenue dans le brillant monde de la bibliothèque standard C++ :-P.

0 votes

Pour C, il est défini dans float.h. limits.h est pour les entiers

34voto

Andrew Hare Points 159332

Essayez ceci :

-1 * std::numeric_limits::max()

Référence : numeric_limits

Cette classe est spécialisée pour chacun des types fondamentaux, avec ses membres retournant ou étant définis sur les différentes valeurs qui définissent les propriétés que ce type a dans la plateforme spécifique dans laquelle il compile.

1 votes

Pourquoi ne pas simplement -numeric_limits::max()?

5 votes

@k06a avoir la négation représentée par un seul caractère dans une si longue expression, où la chaîne dit même "max", est sûr de tromper quelqu'un tôt ou tard. Soit elle est stockée dans une variable descriptive, soit utilisez -1 * ... pour la rendre un peu plus claire.

22voto

Christoph Points 64389

Recherchez-vous l'infini réel ou la valeur finie minimale ? Si c'est le premier cas, utilisez

-numeric_limits::infinity()

ce qui ne fonctionne que si

numeric_limits::has_infinity

Sinon, vous devriez utiliser

numeric_limits::lowest()

qui a été introduit en C++11.

Si lowest() n'est pas disponible, vous pouvez vous rabattre sur

-numeric_limits::max()

qui peut différer de lowest() en principe, mais normalement pas en pratique.

0 votes

+1 pour la différence entre une valeur finie et infinie ! Mais la norme ne garantit pas un encodage de point flottant symétrique. Donc -numeric_limits::max() même si cela fonctionne en pratique n'est pas entièrement portable en théorie.

0 votes

@Christophe: [x] corrigé

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X