OVH Cloud OVH Cloud

std::numeric_limits::min()

38 réponses
Avatar
Alexis Guillaume
Bonjour à tous.

J'aimerais comprendre pourquoi sur mon système (gcc 3.3)
std::numeric_limits<double>::min() vaut 2.22507e-308. Cela me dérange
parce qu'intuitivement je pensais que le minimum serait l'opposé
de std::numeric_limits<double>::max() et que la valeur remarquable
2.22507e-308 aurait un nom spécifique.

Quelles sont les raisons de ce choix ? Je le te trouve étrange dans la
mesure ou la simple fonction suivante ne marche pas avec les double :

template <typename T>
T max( T const * begin, T const * end ) {
T max = std::numeric_limits<T>::min();
while (begin != end) {
if (*begin >= max) max = *begin;
++begin;
}
return max;
}

int main() {
unsigned int t1[] = { 1, 2, 4, 3 };
int t2[] = { -1000, -200, -1, -10 };
double t3[] = { -1, -2, -3, -4 };

std::cout << max(t1, t1 + 4) << "\n" << max(t2, t2 + 4)
<< "\n" << max(t3, t3 + 4) << std::endl;
}

Résultat :
4
-1
2.22507e-308

--
Alexis Guillaume
<http://cowsoft.free.fr> : ressources universitaires en vrac

"Il est minuit. La pluie fouette les vitres."

10 réponses

1 2 3 4
Avatar
Gabriel Dos Reis
Alexis Guillaume writes:

| Bonjour à tous.
|
| J'aimerais comprendre pourquoi sur mon système (gcc 3.3)
| std::numeric_limits<double>::min() vaut 2.22507e-308.

Parce que la norme demande que ce soit la plus petite valeur
positive.

| Cela me dérange
| parce qu'intuitivement je pensais que le minimum serait l'opposé
| de std::numeric_limits<double>::max()

Si tu veux l'opposé de std::numeric_limits<double>::max(), écris

-std::numeric_limits<double>::max()

| et que la valeur remarquable
| 2.22507e-308 aurait un nom spécifique.

Probablement.

| Quelles sont les raisons de ce choix ?

C'est à peut près comme ça wue LIA-1 (Language Independent Arithmetic,
Part 1), définit les choses.

| Je le te trouve étrange dans la
| mesure ou la simple fonction suivante ne marche pas avec les double :
|
| template <typename T>
| T max( T const * begin, T const * end ) {
| T max = std::numeric_limits<T>::min();
| while (begin != end) {
| if (*begin >= max) max = *begin;
| ++begin;
| }
| return max;
| }

Il y a beaucoup de types avec lesquels elle ne marche pas :-)

essaie

template<typename T>
T max(const T* first, const T* last) {
if (first == last)
throw std::logic_error("empty sequence");
return *std::max_element(first, last);
}

-- Gaby
Avatar
Gabriel Dos Reis
"Vincent Lascaux" writes:

| > -std::numeric_limits<double>::max()
|
| Est-on assuré de pouvoir stoquer -std::numeric_limits<double>::max() dans un
| double ?

Oui.

-- Gaby
Avatar
Gabriel Dos Reis
writes:

| Gabriel Dos Reis wrote in message
| news:...
| > Alexis Guillaume writes:
|
| > | J'aimerais comprendre pourquoi sur mon systeme (gcc 3.3)
| > | std::numeric_limits<double>::min() vaut 2.22507e-308.
|
| > Parce que la norme demande que ce soit la plus petite valeur positive.
|
| C'est sans doute ce qu'on a voule, mais ce n'est pas ce que dit en
| fait
| le texte normatif. Tout ce qu'il dit, c'est &#65533; minimum finite
| value &#65533;,
| avec une exception seulement pour des types flottants avec
| d&#65533;normalisation ! Or, si son flottant n'a pas de
| d&#65533;normalisation, &#65533;a
| m'&#65533;tonnerait que la valeur minimum finie ne soit pas
| n&#65533;gative.

Tu connais une implémentation dans le monde réel où c'est le cas ?

| En fait, d'apr&#65533;s les valeurs qu'il a, je suppose qu'il a IEEE.
| Donc, des
| flottants avec d&#65533;normalisation. Et l'exception s'applique. Mais
| je
| n'arrive pas &#65533; crois que la norme a voulu que pour les
| flottants IEEE,
| min soit une valeur positive tr&#65533;s petite, tandis que pour les
| flottants
| format IBM, elle soit une valeur n&#65533;gative avec un exposant
| &#65533;lev&#65533;. M&#65533;me
| si c'est ce qu'ils ont &#65533;crit.

Si ton interprétation ne colle pas avec la réalité, change
d'interprétation :-)

-- Gaby
Avatar
Gabriel Dos Reis
Alexis Guillaume writes:

| À moitié. Je cherche à comprendre ce qui a motivé ce choix qui conduit à
| ce qui m'apparaît être une incohérence. Ta réponse ne fait que reporter
| le problème à DBL_MIN. :-)

Conformité à LIA-1 et l'existant.

-- Gaby
Avatar
Gabriel Dos Reis
"Vincent Lascaux" writes:

| > | > -std::numeric_limits<double>::max()
| > |
| > | Est-on assuré de pouvoir stoquer -std::numeric_limits<double>::max()
| dans un
| > | double ?
| >
| > Oui.
|
| Et est ce que -std::numeric_limits<T>::max() = | std::numeric_limits<T>::min() pour T char, short, int, long (et les autres
| si j'en oublie) ?

Non. Sur des machines à complément à 2, ce n'est certainement pas le cas.

-- Gaby
Avatar
Loïc Joly
Alexis Guillaume wrote:
Bonjour à tous.

J'aimerais comprendre pourquoi sur mon système (gcc 3.3)
std::numeric_limits<double>::min() vaut 2.22507e-308. Cela me dérange
parce qu'intuitivement je pensais que le minimum serait l'opposé
de std::numeric_limits<double>::max() et que la valeur remarquable
2.22507e-308 aurait un nom spécifique.


Ton système est conforme en tout cas :
static T min() throw();
Minimum finite value.181)
For floating types with denormalization, returns the minimum positive
normalized value.

Maintenant, pourqui, je pourrais te dire que c'est pour que ce soit égal
à DBL_MIN, mais je ne suis pas certain que ça te satisfasse...


Quelles sont les raisons de ce choix ? Je le te trouve étrange dans la
mesure ou la simple fonction suivante ne marche pas avec les double :

template <typename T>
T max( T const * begin, T const * end ) {
T max = std::numeric_limits<T>::min();
while (begin != end) {
if (*begin >= max) max = *begin;
++begin;
}
return max;
}


Le code suivant doit marcher, non ?

template <typename T>
T max( T const * begin, T const * end ) {
assert (begin != end);
T max = *begin;
while (begin != end) {
if (*begin >= max) max = *begin;
++begin;
}
return max;
}

--
Loïc

Avatar
Vincent Lascaux
-std::numeric_limits<double>::max()


Est-on assuré de pouvoir stoquer -std::numeric_limits<double>::max() dans un
double ?

--
Vincent

Avatar
kanze
Gabriel Dos Reis wrote in message
news:...
Alexis Guillaume writes:

| J'aimerais comprendre pourquoi sur mon systeme (gcc 3.3)
| std::numeric_limits<double>::min() vaut 2.22507e-308.

Parce que la norme demande que ce soit la plus petite valeur positive.


C'est sans doute ce qu'on a voule, mais ce n'est pas ce que dit en
fait
le texte normatif. Tout ce qu'il dit, c'est &#65533; minimum finite
value &#65533;,
avec une exception seulement pour des types flottants avec
d&#65533;normalisation ! Or, si son flottant n'a pas de
d&#65533;normalisation, &#65533;a
m'&#65533;tonnerait que la valeur minimum finie ne soit pas
n&#65533;gative.

En fait, d'apr&#65533;s les valeurs qu'il a, je suppose qu'il a IEEE.
Donc, des
flottants avec d&#65533;normalisation. Et l'exception s'applique. Mais
je
n'arrive pas &#65533; crois que la norme a voulu que pour les
flottants IEEE,
min soit une valeur positive tr&#65533;s petite, tandis que pour les
flottants
format IBM, elle soit une valeur n&#65533;gative avec un exposant
&#65533;lev&#65533;. M&#65533;me
si c'est ce qu'ils ont &#65533;crit.

--
James Kanze GABI Software
Conseils en informatique orient&#65533;e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S&#65533;mard, 78210 St.-Cyr-l'&#65533;cole, France, +33 (0)1
30 23 00 34

Avatar
Gabriel Dos Reis
James Kanze writes:

| Gabriel Dos Reis writes:
|
| |> writes:
|
| |> | Gabriel Dos Reis wrote in message
| |> | news:...
| |> | > Alexis Guillaume writes:
|
| |> | > | J'aimerais comprendre pourquoi sur mon systeme (gcc 3.3)
| |> | > | std::numeric_limits<double>::min() vaut 2.22507e-308.
|
| |> | > Parce que la norme demande que ce soit la plus petite valeur
| |> | > positive.
|
| |> | C'est sans doute ce qu'on a voule, mais ce n'est pas ce que dit en
| |> | fait le texte normatif. Tout ce qu'il dit, c'est « minimum finite
| |> | value », avec une exception seulement pour des types flottants
| |> | avec dénormalisation ! Or, si son flottant n'a pas de
| |> | dénormalisation, ça m'étonnerait que la valeur minimum finie ne
| |> | soit pas négative.
|
| |> Tu connais une implémentation dans le monde réel où c'est le cas ?
|
| Où quoi c'est le cas ?

std::numeric_limits<double>::min() est négatif. C'est le point crucial.
Le reste, c'est de la distraction.

| Que l'implémentation n'a pas de dénormalisation :
| c'est le cas même de la plupart des formats flottants que je connais --
| sur les gros IBM, les PDP-11 et les Vax d'avant IEEE...

Voir ci-dessus.

| |> | En fait, d'après les valeurs qu'il a, je suppose qu'il a IEEE.
| |> | Donc, des flottants avec dénormalisation. Et l'exception
| |> | s'applique. Mais je n'arrive pas à est ce qu'ils ont écrit.
|
| |> Si ton interprétation ne colle pas avec la réalité, change
| |> d'interprétation :-)
|
| Je n'interprète rien. Je répète simplement ce que la norme dit.

Non, tu répètes simplement ce que tu as dit sur comp.lang.c++.moderated
ou cpmp.std.c++ sans pour autant suscité une fièvre corrective de la
part des implémenteurs ou des gens qui ont maintiennent cette partie
de la norme :-)

-- Gaby
Avatar
Gabriel Dos Reis
James Kanze writes:

| Alexis Guillaume writes:
|
| |> À moitié. Je cherche à comprendre ce qui a motivé ce choix qui
| |> conduit à ce qui m'apparaît être une incohérence.
|
| L'histoire.

Bof. std::numeric_limits<> a été calqué sur LIA-1, qui se démarque
pas mal de IEEE-754; en fait, LIA-1 offre un modèle plus général que
IEEE-754. Ils ne s'excluent pas, mais l'esprit n'est vraiment pas le
même.

-- Gaby
1 2 3 4