Bonjour,
J'aimerais savoir si dans le code source suivant, (a==b) est toujours true ou pas:
Merci d'avance.Code:
1
2
3
4 void fct(float a){ float b = a; // (a==b)==true ??? }
Version imprimable
Bonjour,
J'aimerais savoir si dans le code source suivant, (a==b) est toujours true ou pas:
Merci d'avance.Code:
1
2
3
4 void fct(float a){ float b = a; // (a==b)==true ??? }
Bonjour,
Je suppose que vous faites allusion aux problèmes de comparaison de valeurs réelle liées au nombre de chiffres significatifs.
Il y a eu une discussion dernièrement sur ce sujet.
Mon avis sur la question : en général la comparaison de 2 flottants avec == n'est jamais true.
Dans le cas présent, elle est true, parce que a est réellement égal à b, puisque c'est écrit à la ligne précédente.
Dans le cas général un flottant résulte de calculs, et donc deux flottants ne seront pas égaux.
On peut par exemple écrire
Je crois que ce problème a fait l'objet d'un article dans la FAQ.Code:
1
2
3
4
5 bool Egal(float a, float b, float precis) { if (fabs(a-b) < precis) return true; return false; }
Bonjour,
voici l'article évoqué par Pierre.
Pour répondre à la question initiale, la relation a==b est toujours vraie dans l'exemple.
@Pierre :
En fait, cela dépend beaucoup trop des situations pour donner une réponse catégorique au problème de la pertinence des tests de comparaison de flottants. Il faut traiter ce type de problème au cas par cas.Citation:
Mon avis sur la question : en général la comparaison de 2 flottants avec == n'est jamais true,
Mathématiquement, le problème est fortement lié à la notion de conditionnement qui apparaît en analyse numérique. Les tests vont également différer selon que l'on considère des algorithmes itératifs ou directs.
Dans beaucoup de cas, une bonne solution consiste à mixer un test "exact" (a==b) et un test "approximatif" (fabs(b-a)<tolérance) et à indiquer à l'utilisateur un message différent dans chaque cas.
Bonjour,
Il est vrai que je me place ans le contexte où les valeurs sont des dimensions.
Supposons des float, la précision est de 7 chiffres significatifs. Si le 7è est bon, on dira que les 2 valeurs sont égales, si le 6è est bon, mais le à différent de 1 unité, est-il justifié de dire que les deux valeurs ne sont pas égales mais proches, donc, un traitement différent du premier? je ne pense pas.
Par ailleurs, ce type de test est fait dans un programme qui effectue des quantités de test de ce type.
Donc, pour moi, sauf cas particulier, c'est à dire dans le cas général, l'égalité de 2 réels n'existe pas.
Il serait intéressant de nous donner un exemple où "dans le cas général le test d'égalité entre 2 réels a un sens".
Pour s'en convaincre, voici une petite démonstration, par le contraire (c'est plus facile)
Le programme trouve que a et b sont égaux. CQFD.Code:
1
2
3
4
5
6
7
8
9
10
11
12 int main(int argc, char *argv[]) { float a,b; a=MAXFLOAT; b=MAXFLOAT; a-=1.; b-=10.; if (a==b) printf("Egal\n"); else printf("Différent\n"); while (!kbhit()); return 0; }
Pour mémoire, j'ai utilisé MAXFLOAT comme valeur particulière, en l'occurrence, cela voulait dire "valeur non renseignée, donc inconnue". Dans certains cas que j'ai parfaitement identifiés, la valeur ne valait plus EXACTEMENT MAXFLOAT. J'en suis arrivé à prendre comme valeur test 4607.48 qui elle n'était pas atteinte par la modification "accidentlle" du 7è chiffre significatif.
Bonjour,
tout d'abord, je pense ne pas comprendre le sens donné au mot "dimensions" dans votre phrase :
J'ai une petite remarque concernant ceci :Citation:
Il est vrai que je me place dans le contexte où les valeurs sont des dimensions.
La précision d'un float peut théoriquement varier, par exemple en fonction de l'architecture ou du système d'exploitation (voir le fichier float.h). La précision actuelle d'un float sera très certainement différente de celle(s) que l'on trouvera dans les prochaines années.Citation:
Supposons des float, la précision est de 7 chiffres significatifs.
Quelles sont vos raisons? Dans votre premier message vous avez écrit :Citation:
Supposons des float, la précision est de 7 chiffres significatifs. Si le 7è est bon, on dira que les 2 valeurs sont égales, si le 6è est bon, mais le à différent de 1 unité, est-il justifié de dire que les deux valeurs ne sont pas égales mais proches, donc, un traitement différent du premier? je ne pense pas.
Ce raisonnement n'est pas juste. D'une part, les flottants ne résultent pas nécessairement de calculs (constantes physiques/mathématiques,paramètres de tolérance/précision, etc). D'autre part, lorsque c'est le cas, deux flottants issus de calculs différents peuvent être égaux à la précision choisie pour vos opérations (si les nombres 1.23456789 et 1.23456788 sont les résultats théoriques de deux calculs différents et sont stockés dans vos "float", ils seront considérés égaux.)Citation:
Dans le cas général un flottant résulte de calculs, et donc deux flottants ne seront pas égaux.
Je ne vois pas ce qui permet d'affirmer cela. J'imagine que vous voulez écrire que dans ce cas là, la coexistence de deux tests comparatifs dont l'un semble redondant à l'autre implique une perte de performances. C'est parce que vous voyez les choses comme ceci :Code:
1
2 Par ailleurs, ce type de test est fait dans un programme qui effectue des quantités de test de ce type.
alors qu'il faut les voir comme cela :Code:
1
2
3
4
5
6
7
8
9
10
11 float a,b; // ...calculs avec a et b... if (a==b) { // cas où a et b sont égaux à la précision du calculateur } else if (fabs(b-a)<=tolerance) { // cas où a et b sont égaux à la tolérance utilisateur }
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14 float a,b; // ...calculs avec a et b... if (fabs(b-a)<=tolerance) { if (a==b) { // cas où a et b sont égaux à la précision du calculateur } else { // cas où a et b sont égaux à la tolérance utilisateur } }
Les opérations élémentaires (+,-,*,/) sur les flottants peuvent générer des erreurs d'arrondi en précision finie. Pour paraphraser l'article de la faq :
L'accumulation des erreurs d'arrondis est une chose qui peut être analysée très finement. En analyse numérique, on utilise des modèles d'arithmétique flottante pour cela.Code:
1
2 Ces imprécisions deviennent d'autant plus gênantes qu'elles s'accumulent en même temps que les opérations que vous effectuez sur vos nombres ; ainsi il est tout à fait possible d'obtenir des nombres très éloignés des résultats théoriques.
L'un des pionniers du domaine est Wilkinson. Le livre d'Higham est une belle introduction à ces questions.
Un domaine typique où on a recours aux tests que vous préconisez est la géométrie algorithmique, par exemple dans la génération des maillages simpliciaux par l'algorithme de Delaunay.
Ceci est notamment dû au fait que l'on gère simultanément une représentation flottante et une représentation graphique (entiers<->pixels) des triangulations.
Que démontrez-vous?Citation:
Pour s'en convaincre, voici une petite démonstration, par le contraire (c'est plus facile)
Le programme trouve que a et b sont égaux. CQFD.Code:
1
2
3
4
5
6
7
8
9
10
11
12
13 int main(int argc, char *argv[]) { float a,b; a=MAXFLOAT; b=MAXFLOAT; a-=1.; b-=10.; if (a==b) printf("Egal\n"); else printf("Différent\n"); while (!kbhit()); return 0; }
Par exemple, tous les algorithmes itératifs qui possèdent une propriété de convergence et sont stables-vers-l'avant (forward stability) : la valeur limite peut-être testée à la précision du calculateur.Citation:
Il serait intéressant de nous donner un exemple où "dans le cas général le test d'égalité entre 2 réels a un sens".
Ce problème d'égalité ou non de flottant est beaucoup moin compliqué que vous vous imaginez.
1- une dimension peut être une longueur, un angle, une latitude, une aire, mais pas un prix.
2- un float est sur 32 bits ce qui implique forcément 7 chiffres significatifs, s'il était sur 64 bits on appellerait ça un double (15 chiffres)
Un réel au sens mathématique se différencie d'un entier par ses décimales. Lorsqu'on écrit la 3ème décimale et pas la quatrième, c'est qu'on a arrondi à 1/1000, mais rien ne dit que la quatrième décimale est 0 ainsi que les suivantes.Citation:
Citation:
Supposons des float, la précision est de 7 chiffres significatifs. Si le 7è est bon, on dira que les 2 valeurs sont égales, si le 6è est bon, mais il est différent de 1 unité, est-il justifié de dire que les deux valeurs ne sont pas égales mais proches, donc, un traitement différent du premier? je ne pense pas.
Quelles sont vos raisons? Dans votre premier message vous avez écrit :
Citation:
Dans le cas général un flottant résulte de calculs, et donc deux flottants ne seront pas égaux.
Ce raisonnement n'est pas juste. D'une part, les flottants ne résultent pas nécessairement de calculs (constantes ...
Les flottant, c'est strictement la même chose. Quand on fait du calcul numérique avec une table de logarithme avec une table à 5 chiffres, on dispose de 5 chiffres significatifs, amis rien ne dit que le 6è chiffre n'est pas 4.
Bien sûr un flottant peut ne pas résulter de calcul. Vous parlez de calculs constantes mathématiques. Testez cet exemple
Code:
1
2
3 float c = M_PI; if (c == M_PI) printf("c est Egal à PI\n"); else printf("c est Différent de PI\n");
Tout simplement parce que je sais ce que font les programme que j'écris :mouarf:Citation:
Par ailleurs, ce type de test est fait dans un programme qui effectue des quantités de test de ce type.
Citation :
Je ne vois pas ce qui permet d'affirmer cela. J'imagine que vous voulez écrire que dans ce cas là, la coexistence de ...
Dans vos exemples, que fera le programme dans l'une ou l'autre solution? En quoi sont-elles différentes ?
Je dis que soit un float a une valeur conventionnelle, type MAXFLOAT et on peut tester l'égalité, le résultat du test aura un sens et le programme pourra agir en conséquence, sinon, il est nécessaire de faire le test avec une certaine tolérance sinon, le résultat du test aura (statistiquement) une chance sur 2 d'être faux. En effet, le dernier chiffre a la même probabilité d'être arrondi par défaut que par excès.
Concernant l'accumulation des imprésions, c'est un peu plus compliqué que cela.
Petit problème intellectuel : soient 2 segments de droite, définis par les coordonnées XY de leurs extrémités et qui se coupent.
Soit I le point d'intersection. On calcule XI et YI, les coordonnées de ce point.
Quelle est la distance du point I à chacun des deux segments ?
Vous avez implémenté la triangulation de Delaunay ou vous avez lu de la doc ? Moi, je l'ai implémentée.
Ce que je veux démontrer avec mon petit exemple est que 2 flottants manifestement inégaux (au sens mathématique) sont testés égaux.
Votre exemple d'algorithme itératif, convergeant et stable vers l'avant est certainement un très bon exemple, mais je ne traite que de dimension.
Ceci me rappelle tout une petite anecdote. Vers les années 87-88, les problèmes de performance étaient importants. Or dans notre spécialité l'utilisation de la racine carrée (sqrt) était fréquente, et donc, on cherchait tous les moyens de l'éviter. Il me semble que c'est un bon exemple d'algorithme itératif, convergeant et stable. Dans l'espoir de plaire à mon directeur, j'avais fait un algorithme qui calculait la racine carrée, mais avec la précision nécessaire et non superflue. Cet algorithme était naturellement plus rapide que celui de la librairie (Fortran sur IBM)
Bonjour,
Je ne vois toujours pas ce qu'est une dimension malgré vos exemples.Citation:
une dimension peut être une longueur, un angle, une latitude, une aire, mais pas un prix.
Pouvez-en vous en donner une définition précise?
Je ne comprends pas.Citation:
un float est sur 32 bits ce qui implique forcément 7 chiffres significatifs, s'il était sur 64 bits on appellerait ça un double (15 chiffres)
La précision double est disponible sur les architectures 32 bits.
Ce que j'entends par "float" est tout nombre pouvant être stocké sans perte de précision dans une variable de type float en C/C++. Peut-être en avez-vous une définition différente?
En mathématiques un entier est un réel.Citation:
Un réel au sens mathématique se différencie d'un entier par ses décimales.
L'ensemble Z des entiers relatifs est strictement inclus dans le corps R des nombres réels.
L'arrondi de x est différent de x et on peut compléter ses décimales par zéro à l'infini. C'est d'ailleurs pour cette raison que votre exempleCitation:
Lorsqu'on écrit la 3ème décimale et pas la quatrième, c'est qu'on a arrondi à 1/1000, mais rien ne dit que la quatrième décimale est 0 ainsi que les suivantes.
affiche "c est Différent de PI\n" sur votre machine. Ouvrez le fichier math.h et vous y lirez sûrement :Code:
1
2
3
4 float c = M_PI; if (c == M_PI) printf("c est Egal à PI\n"); else printf("c est Différent de PI\n");
Je ne discuterai pas le fait que M_PI n'est pas typé ici. Il est clair étant donné le commentaire qui précède ces définitions qu'en C++ on pourrait tout aussi bien définir M_PI comme ceci (en laissant les décimales superflues) :Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 /* Traditional/XOPEN math constants (double precison) */ #ifndef __STRICT_ANSI__ #define M_E 2.7182818284590452354 #define M_LOG2E 1.4426950408889634074 #define M_LOG10E 0.43429448190325182765 #define M_LN2 0.69314718055994530942 #define M_LN10 2.30258509299404568402 #define M_PI 3.14159265358979323846 #define M_PI_2 1.57079632679489661923 #define M_PI_4 0.78539816339744830962 #define M_1_PI 0.31830988618379067154 #define M_2_PI 0.63661977236758134308 #define M_2_SQRTPI 1.12837916709551257390 #define M_SQRT2 1.41421356237309504880 #define M_SQRT1_2 0.70710678118654752440 #endif
Par conséquent, la variable c à la ligneCode:
1
2 double const M_PI = 3.14159265358979323846;
est destinée à contenir un arrondi de M_PI. Le test d'égalité est vrai si la variable c est typée double.Code:
1
2float c = M_PI;
Je ne vois pas en quoi comparer M_PI (double) à son arrondi c (float) et montrer que le booléen "M_PI==c" est faux est un argument en faveur de la non-pertinence des tests d'égalité entre deux floats.
C'est simple. En ajoutant un paramètre de tolérance pour comparer les flottants vous altérez potentiellement la précision de vos calculs. Par exemple, on peut considérer un schéma comme celui-ci :Citation:
Dans vos exemples, que fera le programme dans l'une ou l'autre solution? En quoi sont-elles différentes ?
Le choix du paramètre de tolérance (tol) peut influer très significativement sur l'erreur commise sur la valeur théorique que devrait contenir la variable c.Code:
1
2
3
4
5
6 float a,b,c,tol; // initialisation de tol // série de calculs dont le résultat final est stocké dans la variable a b = mon_calcul_de_b_a_ma_tolerance(tol); c = a/fonction_mathematique_de_parametre(b);
Une démarche courante en algèbre linéaire consiste à adopter la démarche inverse : plutôt que d'altérer la précision du calculateur à l'aide d'une tolérance souvent difficile à choisir a priori, on accepte de perdre en performances en effectuant certains calculs avec une précision meilleure que celle de la machine (voir par exemple la bibliothèque XBLAS). Ces calculs sont déterminés après une analyse numérique de l'algorithme considéré.
L'exemple classique concerne l'algorithme de raffinement itératif de la solution calculée d'un système d'équations linéaire et inversible (théorème 3.1 de ce papier).
Dans la mesure du possible, il est préférable de ne pas altérer la tolérance de la machine. Il existe bien sûr de nombreux cas où on peut le faire mais il faut savoir les identifier, c'est-à-dire mesurer les conséquences d'un tel choix en majorant l'erreur commise sur la quantité calculée (voir théorème 3.2 du papier pour une analyse du raffinement itératif avec une précision fixée).
Quand ajouter un test d'égalité entre deux flottants?
Dans le cas itératif, lorsque vous êtes sûr de la convergence et de la stabilité de votre algorithme :
Il s'avère alors que les erreurs d'arrondi n'empêchent pas la convergence de la méthode de calcul mais en ralentissent simplement la convergence.Code:
1
2
3
4
5 if (valeur_calculée==limite_theorique) { // convergence obtenue }
Dans le cas direct, lorsque l'égalité a une signification particulière. Par exemple, pour la détection des pivots nuls dans le procédé d'élimination de Gauss (division par zéro) :
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 float pivot,facteur_d_elimination; // début du procédé if (fabs(pivot)<=plus_petit_nombre_par_lequel_on_peut_diviser_un_float) { if (pivot==0.0) { // la matrice à triangulariser est singulière return code_erreur_pour_singularite; } else { // la matrice à triangulariser est mal conditionnée return code_erreur_pour_mauvais_conditionnement; } } facteur_d_elimination = un_certain_coefficient / pivot; // on continue le procédé
Votre question n'a pas de sens : l'erreur commise sur la distance dépend de votre algorithme et de la distance que vous choisissez.Citation:
Concernant l'accumulation des imprésions, c'est un peu plus compliqué que cela.
Petit problème intellectuel : soient 2 segments de droite, définis par les coordonnées XY de leurs extrémités et qui se coupent.
Soit I le point d'intersection. On calcule XI et YI, les coordonnées de ce point.
Quelle est la distance du point I à chacun des deux segments ?
Par ailleurs, c'est aussi compliqué que cela, puisque c'est exactement ce dont traite le lien que j'ai précédemment donné (forward stability).
Félicitations, nous sommes deux et sûrement beaucoup d'autres sur ce forum. Quel est le rapport avec la discussion?Citation:
Vous avez implémenté la triangulation de Delaunay ou vous avez lu de la doc ? Moi, je l'ai implémentée.
Les algorithmes itératifs qui calculent des longueurs, des aires, des angles, etc, ne manquent pas.Citation:
Votre exemple d'algorithme itératif, convergeant et stable vers l'avant est certainement un très bon exemple, mais je ne traite que de dimension.
Précisez : quel agorithme? Quelle stabilité?Citation:
Or dans notre spécialité l'utilisation de la racine carrée (sqrt) était fréquente, et donc, on cherchait tous les moyens de l'éviter. Il me semble que c'est un bon exemple d'algorithme itératif, convergeant et stable. Dans l'espoir de plaire à mon directeur, j'avais fait un algorithme qui calculait la racine carrée, mais avec la précision nécessaire et non superflue. Cet algorithme était naturellement plus rapide que celui de la librairie (Fortran sur IBM)
Que de questions;)
Une dimension est une valeur qui correspond à une quantité mesurable.
Lorsque vous mesurez une quantité (longueur, masse, temp etc), vous le mesurez avec un appareil adapté. La mesure fournie a une certaine précision, indépendamment de toute erreur, c'est ce qu'on appelle en mathématique un nombre réel.
Lorsque vous faites des opérations avec ces nombres, vous les considérez avec leurs décimales et non pas leur réalité physique puisqu'elle est inconnue. Je veux dire par là que si on avait pris un appareil plus précis, on aurait plus de décimales. Certaines opérations nécessitent des multiplications, c'est le cas bien connu des calculs d'aire. Si vous multipliez de nombres à 7 chiffres significatifs, vous obtenez un nombre à 7 chiffres. Si ensuite vous faites un soustraction, il ne restera par exemple que 4 chiffres. C'est inévitable, et ce problème est bien connu des programmeurs. Il existe donc des astuces pour améliorer la précision.
Float et double.
Un float est sur 32 bits, même si l'architecture prévoit des mots de 8 bits. Le type float ou double n'a rien à voir avec l'architecture. Il n'y pas si longtemps, les machines travaillaient sur 16 bits, cela n'empêchait pas d'avoir des float sur 32 bits et des doubles sur 64 bits.
Il est possible que les architectures sur 64 bits fournissent de float sur 64 bits, je n'en sais rien, de la même façon que sur une machine 32 bits un long ET un int sont tous deux sur 32 bits.
Rectification : un entier est AUSSI un réel. Ce n'est pas du tout pareil.Citation:
En mathématiques un entier est un réel.
L'ensemble Z des entiers relatifs est strictement inclus dans le corps R des nombres réels.
C'est à dire soit a appartenant à N , cela n'implique pas que a/2 appartienne à N.
A propos du test avec M_PI, là vraiment, je ne sais pas quoi dire. Il est bien évident que si un a deux déclarées valeurs égales dans le code, le test d'égalité ne peut être que true.
A l'occasion, vous m'expliquerez pourquoi et comment l'introduction d'une tolérance lors des test de comparaison peuvent altérer la précision des calculs.
Il n'y a pas des quantités d'algorithmes pour calculer une intersection, soit on travaille pas projections successives, soit on fait le calcul analytique. Je ne sais pas si la première méthode est très utilisée. Si vous en connaissez une troisième, je suis preneur. Quand je parle de la distance d'un point à un segment, je parle naturellement de la distance la plus courte qui est égale à la longueur de la projection. On est en géométrie Euclidienne.Citation:
Votre question n'a pas de sens : l'erreur commise sur la distance dépend de votre algorithme et de la distance que vous choisissez.
Désolé, je passe directement à la dernière ligne.
Ma spécialité (pourquoi stabilité ?) c'est les calculs relatifs à la DAO, CAO, SIG) (Dessin et conception assistée par ordinateur et Système d'information géographique)
Bonsoir,
Vous ne savez pas ce qu'est un nombre réel.Citation:
Une dimension est une valeur qui correspond à une quantité mesurable.
Lorsque vous mesurez une quantité (longueur, masse, temp etc), vous le mesurez avec un appareil adapté. La mesure fournie a une certaine précision, indépendamment de toute erreur, c'est ce qu'on appelle en mathématique un nombre réel.
La définition est ici.
Merci pour la précision. C'est clair pour moi maintenant.Citation:
Float et double.
Un float est sur 32 bits, même si l'architecture prévoit des mots de 8 bits. Le type float ou double n'a rien à voir avec l'architecture. Il n'y pas si longtemps, les machines travaillaient sur 16 bits, cela n'empêchait pas d'avoir des float sur 32 bits et des doubles sur 64 bits.
Il est possible que les architectures sur 64 bits fournissent de float sur 64 bits, je n'en sais rien, de la même façon que sur une machine 32 bits un long ET un int sont tous deux sur 32 bits.
Je maintiens : un entier est un réel (Z inclus dans R).Citation:
Rectification : un entier est AUSSI un réel. Ce n'est pas du tout pareil.Citation:
En mathématiques un entier est un réel.
L'ensemble Z des entiers relatifs est strictement inclus dans le corps R des nombres réels.
Variation : tous les entiers sont des réels (Z inclus dans R).
Bien évidemment, les entiers ne sont pas les réels (Z différent de R).
Bien évidemment, les réels ne sont pas nécessairement des entiers (R n'est pas inclus dans Z).
Que démontrez-vous?Citation:
Rectification : un entier est AUSSI un réel. Ce n'est pas du tout pareil.
C'est à dire soit a appartenant à N , cela n'implique pas que a/2 appartienne à N.
Quel est le rapport logique entre vos phrases?
Pour rappel, la définition de l'ensemble des entiers naturels est ici.
Pour rappel, N n'est pas un corps : la multiplication et la division n'y sont pas définies.
Vous argumentez sur le fait qu'on ne doit pas comparer deux flottants en donnant un exemple dans lequel vous faîtes la comparaison entre une variable typée float et une variable implicitement typée double.Citation:
A propos du test avec M_PI, là vraiment, je ne sais pas quoi dire. Il est bien évident que si un a deux déclarées valeurs égales dans le code, le test d'égalité ne peut être que true.
Vous ne voyez vraiment pas le problème?
Je vous ai déjà donné un exemple...Citation:
A l'occasion, vous m'expliquerez pourquoi et comment l'introduction d'une tolérance lors des test de comparaison peuvent altérer la précision des calculs.
Vous voulez calculer le rapport c=a/b et b est calculée avec une erreur e. En précision finie, vous calculez en fait a/(b+e).
Par défaut, e va dépendre de la précision du calculateur. Si vous introduisez votre propre tolérance pour vérifier l'exactitude de b, elle en dépendra.
Je ne vous parle pas de la méthode, je vous parle de l'algorithme. L'implémentation de votre méthode si vous préférez.Citation:
Il n'y a pas des quantités d'algorithmes pour calculer une intersection, soit on travaille pas projections successives, soit on fait le calcul analytique. Je ne sais pas si la première méthode est très utilisée. Si vous en connaissez une troisième, je suis preneur.
Pour une méthode, plusieurs implémentations sont possibles.
Certaines sont plus stables que d'autres.
La définition d'une distance est ici.Citation:
Quand je parle de la distance d'un point à un segment, je parle naturellement de la distance la plus courte qui est égale à la longueur de la projection. On est en géométrie Euclidienne.
Plusieurs distances peuvent être définies dans l'espace euclidien.
Quant à la "projection", elle peut être oblique ou orthogonale.
J'avais bien évidemment compris que vous parliez de la distance euclidienne et de la projection orthogonale. J'essayais seulement de vous faire réagir pour que vous soyez plus précis dans vos réponses.
Je ne vous ai pas demandé votre spécialité.Citation:
Ma spécialité (pourquoi stabilité ?) c'est les calculs relatifs à la DAO, CAO, SIG) (Dessin et conception assistée par ordinateur et Système d'information géographique)
Je vous ai demandé de quel algorithme vous parlez et quelle est la propriété de stabilité que vous lui attribuez.
Prenez le temps de lire ce que j'écris.
Je prends le temps de le faire pour avoir un débat constructif parce que la question initiale que vous avez soulevée est intéressante.
Contrairement aux apparences, je ne recherche pas la joute intellectuelle. Je fais exprès de vous provoquer. Je suis plus amical qu'il n'y paraît! ^^ (<- c'est moi!!!)
Ca ne sert a rien de vouloir convaincre en brandissant son palmares professionnel ou ses diplômes : la raison suffit. ;)
Là j'avoue que je ne comprend pas où vous voulez en venir.
Pour mémoire, je déteste qu'on me renvoie des liens pour preuve de ce qu'on avance.
Pour clore ce débat complètement stérile et qui apparemment n'intéresse personne, je vais vous confier un secret. Etant donné ce problème inévitable lié à la comparaison de flottants, pour les coordonnées et autre dimensions, je travaille en long, je gagne ainsi 2 à 3 chiffres significatifs, pour la même occupation mémoire.
Bonne nuit.
T'expliquer que l'analyse numérique c'est un peu plus compliqué que juste des préjugés de type 'les float/double ça ne se compare pas'. Ben pas de chance, il te montre que dans certains cas c'est pertinent.
T'as la science infuse toi ? Parce que moi, non. Et avoir des liens vers des articles permet d'illustrer, d'approfondir, de justifier, etc...
Ben, non. J'ai trouvé les réponses d'Aleph69 d'une grande qualité et très convainquantes. Etant donné que le problème initial revient souvent, je vais probablement garder au chaud l'adresse de cette discussion. Bref, cette discussion est fort intéressante par les réponses d'Aleph et ton rôle de Candide a un côté rafraichissant ;)
Bonjour 3DArchi.
Je sais que je vais avoir droit à un nouvel avertissement.:P
Pour votre information, si je déteste qu'on me renvoie des liens pour preuve de ce qu'on avance, c'est parce qu'on ne donne aucune explication. Or, un forum est plutôt pour moi un lieu d'échange.
Je préfère un argument plus ou moins bien ficelé qu'un lien sur un article.
Le lien sur "Diistance" est assez intéressant.
Ben (autre orthographe Bin je ne sais pas laquelle des deux adopter) à propos du dernier paragraphe merci sincèrement pour le qualificatif. Je suis très touché.
Code à tester
Code:
1
2
3 float c=3.0/7.0; if (c == 3.0/7.0) printf("Egal\n"); else printf("Différent !!\n");
Toujours à propos de flottants, il y a un excellent document :
http://docs.sun.com/source/806-3568/ncg_goldberg.html
A lire à tête reposée par contre ;)
Salut,Excuses-moi, mais, quand on donne un lien comme celui de wikipedia sur les nombres réels, sur les nombres entiers, ou encore sur les distances, il devient difficile de prétendre que l'on ne donne aucune explication.
Au contraire, on donne la meilleure explication qui soit car on permet à l'autre de prendre "ce qui l'intéresse" dans l'explication donnée par le lien, en évitant les explications laborieuses ou incomplète et en évitant que la réponse ne se transforme en véritable roman (ca, c'est plutôt ma spécialité :D)
Après, celui qui poste le lien n'y peu rien si son vis-à-vis décide de ne rien prendre du lien en... ne cliquant pas dessus :aie:
Bonjour Koala,
Il est vrai que je n'aime pas beaucoup qu'on me réponde pas un lien sur un article de Wikipédia. Mais naturellement je vais voir.
Plusieurs raisons, la principale est celle que j'ai dite, je préfère une réponse adaptée au sujet en cours que de fermer la discussion, du type "donc, j'ai raison".
Autre raison importante, Wikipédia est une encyclopédie de vulgarisation, dont les articles ne sont pas signés.
A moins que les notions de nombre réel et de distance aient changé depuis l'époque de mes études, (je sais, ça fait longtemps), je sais ce que c'est.
Pour info, j'ai vu une très jolie faute dans un article de Wikipédia. Cet article m'avait été indiqué par un membre très actif et très diplômé d'un autre forum, mais c'était "parole de vérité".
Mais on s'éloigne vraiment du sujet primitif : avez-vous exécuté les 3 lignes de code proposées.
Pour complément, dans le même document, il est dit quelques pages plus loin :
On veut calculer z=1/(x-y);
A NE PAS FAIRE if ( x != y) parce que il est possible que x-y = 0.
A FAIRE if (x-y != 0)
Là on est vraiment dans le cœur du sujet
Effectivement, il est possible qu'une erreur d'arrondi se glisse dans le calcul de x-y.Citation:
Pour complément, dans le même document, il est dit quelques pages plus loin :
On veut calculer z=1/(x-y);
A NE PAS FAIRE if ( x != y) parce que il est possible que x-y = 0.
A FAIRE if (x-y != 0)
Là on est vraiment dans le cœur du sujet
Si je comprends bien, vous êtes finalement tombé d'accord avec le fait qu'il soit parfois pertinent de comparer deux flottants puisque vous semblez prôner la comparaison de x-y avec 0...
Dans l'exemple, il me semble également qu'il faille vérifier que x-y n'est pas inférieur au plus petit flottant par lequel on puisse diviser un autre flottant.
En conséquence, tester si x-y est différent de 0 n'est pertinent que s'il a une signification particulière. Par exemple, comme dans le cas de l'élimination gaussienne que je vous ai proposé dans un précédent message.
C'est pourquoi j'ai écrit que mixer une comparaison avec une certaine tolérance (ici, le plus petit flottant par lequel on peut diviser un autre flottant) et une comparaison "exacte" (x-y!=0) peut s'avérer être un choix judicieux dans certains cas.
Vous comprenez?
Concernant vos trois lignes de code, elles montrent que des erreurs d'arrondi peuvent s'introduire dans les calculs mais personne n'a jamais prétendu le contraire.