Bonjour,
Si je crée une map de cette façon : std::map<float, int>, comment la comparaison entre les clefs va elle se faire ?
Un simple == entre deux float ?
Merci d'avance...
Bonjour,
Si je crée une map de cette façon : std::map<float, int>, comment la comparaison entre les clefs va elle se faire ?
Un simple == entre deux float ?
Merci d'avance...
std::map n'utilise pas l'égalité, mais une relation d'ordre. Cela utilisera toujours et uniquement l'opérateur <.
Mieux que SDL : découvrez SFML
Mes tutoriels 2D/3D/Jeux/C++, Cours et tutoriels C++, FAQ C++, Forum C++.
Merci pour ta réponse.
Quand on utilise la fonction insert de std::map, je comprend parfaitement qu'il n'a pas besoin d'utiliser "==".
Mais quand on va rechercher un élément comme ceci: maMap[2.5], il doit bien utiliser le "==" ? autrement je voit pas comment il ferait !
C'est du a une propriété mathematique toute bete, mais a laquelle on ne pense pas immédiatement : si 2 nombres sont égaux, A < B et B < A renvoient tous les deux FALSE.
Exemple :
A = 2, B = 3.
A < B renvoie TRUE
B < A renvoie FALSE
A = 3, B = 2
A < B renvoie FALSE
B < A renvoie TRUE
A = 2, B = 2
A < B renvoie FALSE
B < A renvoie FALSE
C'est une chose qu'il ne faut pas oublier de prendre en compte lorsqu'on surcharge l'opérateur <
A part ca, meme pour un insert on a besoin de reconnaitre les cas d'egalité, puisque la map doit s'assurer de ne pas avoir de doublon![]()
Ouais je vois mais donc un map<float, int> ça n'a fonctionnera pas bien dans ce cas à cause de l'imprecision des float alors :
float a=1.0f;
float b=2.1f-1.1f;
maMap[a] = 5;
maMap[b] = 8;
Il risque de m'ajouter 2 données différentes dans la map alors que "a" et "b" sont cencé être de la même valeur. C'est bien ça ?
L'imprécision dans les calculs sur flottant n'apparait pas au petit bonheur la chance, dans ton calcul a et b contiennent exactement la même chose.
Cela n'a de risque d'arriver que si tu fais des division. Par exemple il se peut que dans les formules 2.0/3.0 et (1.0/3.0)*2.0 les tout derniers bits utilisés pour représenter la valeur 0.666... soient différents.
Dans l'absolu, il est vrai que si il y a une différence de ne serais-ce qu'un millionième entre deux flottants map créera deux entrées différentes.
Si cela te pose un problème, il est possible de personnaliser le foncteur utilisé par map pour faire les comparaisons pour lui imposer une précision limitée (à 1,2,3 chiffres après la virgule par exemple).
Salut,Etant donné que la std::map utilise seulement l'opérateur plus petit, elle considère que si
a n'est pas plus petit que b et que
b n'est pas plus petit que a alors
a est égal à b...
Il faut noter que, dans certains cas, cela risque d'apporter quelques bugs originaux (même si je n'ai aucune idée de ce qu'ils peuvent être)
Comme quoi, il y a parfaitement moyen de ne travailler qu'avec l'opérateur "plus petit"
Evidemment, il reste le fait que les réels (floats ou doubles d'ailleurs) souffrent d'une imprécision qui est, principalement due à la représentation binaire.
Comme toute comparaison entre des réels, il faut donc penser à prendre en compte le "décalage" en dessous duquel un nombre reste identique, c'est à dire s'il se trouve entre les X - std::limits<float>::epsilon() et X + std::limits<float>::epsilon() (où X est le nombre utilisé)
L'un dans l'autre, ca pourrait très bien servir de "théorie" pour créer le foncteur ad-hoc![]()
A méditer: La solution la plus simple est toujours la moins compliquée
Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
Compiler Gcc sous windows avec MinGW
Coder efficacement en C++ : dans les bacs le 17 février 2014
mon tout nouveau blog
Merci pour vos réponses.
zais_ethael j'aurais logiquement le même raisonnement que toi à propos des float mais :
1) Dans la FAQ, j'ai vu :
http://cpp.developpez.com/faq/cpp/?p...ions_flottants
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 float f1 = 0.1f; float f2 = 1.1f; float f3 = f2 - f1; // Version incorrecte ne tenant pas compte des imprécisions if (f3 == 1.0f) { // Pratiquement jamais vrai ! }
2) Ce programme m'affiche "2" à l'execution :
Alors que si je remplace la ligne "float b=2.1f-1.1f;" par "float b=1.0f;",le programme m'affiche "1" !!!
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 #include <iostream> #include <map> using namespace std; int main() { std::map<float, int> maMap; float a=1.0f; float b=2.1f-1.1f; maMap[a] = 5; maMap[b] = 8; cout<<maMap.size()<<endl; return 0; }
Partager