Python flottant nombre de point de comparaison
Je suis juste revoir quelques notions de base de Python et il y a un problème épineux sujet de la comparaison des nombres à virgule flottante.
2.2 * 3.0 == 6.6
3.3 * 2.0 == 6.6
Je pensais que ceux-ci devraient à la fois le retour d'un Faux. Cependant, la deuxième on m'a donné un Vrai.
Merci de m'aider ici. Merci!
Vous ne serez jamais comparer deux nombres réels par
Une bonne comparaison est plus compliqué que cela, puisque la précision de chars est un certain nombre de chiffres, pas d'une absolue valeur numérique. Quelque chose comme
Hein? Vous pouvez comparer deux nombres en virgule flottante pour l'égalité à l'aide de
Non, Steve a dit "de ne pas utiliser
Et quand est-ce? Presque toujours, quand vous pensez que vous voulez vérifier l'égalité de nombres à virgule flottante, vous vous trompez, et vous n'avez pas. Si vous êtes dans une situation où vous avez vraiment vous voulez vérifier, vous savez mieux. Steve conseils n'est pas de la superstition ou nuisible; c'est une règle de base que les gens devraient suivre jusqu'à ce qu'ils exécutent dans une situation où ils disent, "tiens, ici, j'ai vraiment soin sur les N bits fraction binaire" (ou "... à propos de la séquence de bits" ou quoi que ce soit), à quel point ils vont comprendre que les règles ont des exceptions.
==
. Utilisation abs(a-b) < Threshold
si vous le voulez vraiment.Une bonne comparaison est plus compliqué que cela, puisque la précision de chars est un certain nombre de chiffres, pas d'une absolue valeur numérique. Quelque chose comme
abs(a-b) <= rel_prec * max(abs(a), abs(b))
est mieux (avec rel_prec près de 1e-16, par exemple, pour Python double précision flotteurs). En plus de cela, le cas d'une valeur de zéro doit être manipulé trop. Je n'ai pas pleinement le vérifier, mais ce qui suit peut fonctionner: abs(a-b) <= rel_prec * (max(abs(a), abs(b)) if a != 0 != b else 1)
.Hein? Vous pouvez comparer deux nombres en virgule flottante pour l'égalité à l'aide de
==
. Il fonctionne correctement.Non, Steve a dit "de ne pas utiliser
==
pour comparer deux nombres à virgule flottante." C'est horrible de conseils et applique injustifiée superstitions.Et quand est-ce? Presque toujours, quand vous pensez que vous voulez vérifier l'égalité de nombres à virgule flottante, vous vous trompez, et vous n'avez pas. Si vous êtes dans une situation où vous avez vraiment vous voulez vérifier, vous savez mieux. Steve conseils n'est pas de la superstition ou nuisible; c'est une règle de base que les gens devraient suivre jusqu'à ce qu'ils exécutent dans une situation où ils disent, "tiens, ici, j'ai vraiment soin sur les N bits fraction binaire" (ou "... à propos de la séquence de bits" ou quoi que ce soit), à quel point ils vont comprendre que les règles ont des exceptions.
OriginalL'auteur Zhiya | 2014-09-29
Vous devez vous connecter pour publier un commentaire.
Cela pourrait être éclairante:
Bien qu'ils sont tous affichés en décimal comme
6.6
, lorsque vous examinez la représentation interne, deux d'entre eux sont représentés de la même manière, alors que l'un d'eux ne l'est pas.6.6
. En 3.x,print(2.2 * 3.0)
ou tout simplement2.2 * 3.0
montrera6.6000000000000005
. En 2.x, leprint
tronques, mais juste2.2 * 3.0
sera encore6.6000000000000005
. Donc, c'est plus simple de voir que la réponse, cela implique.Ah, à droite. Je suppose, n'est-ce pas vérifier.
OriginalL'auteur Amadan
Afin de compléter Amadan la bonne réponse, ici est un moyen évident de voir que 2.2*3. et 3.3*2. ne sont pas représentés par le même flotteur: en Python, shell,
En fait, le Python shell affiche le représentation de nombres, qui, par définition, devrait permettre à l'correspondant à flotteur pour être correctement construite à partir de la représentation, vous voyez l'approximation numérique de 2,2*3 que Python n'. Le fait que 2.2*3. != 3.3*2. est évident en voyant tous les chiffres, comme ci-dessus.
print(2.2*3.)
vous donnera6.6000000000000005
. En 3.x, les deuxstr
etrepr
retour de la plus courte chaîne qui permettra d'évaluer, à la mêmefloat
; en 2.x,str
tronque à une plate-forme spécifique nombre de chiffres, de même querepr
ne l'est pas.Intéressant. Il n'y a pas de "partie au sujet de la représentation par rapport à la version imprimée du" avant votre commentaire. 😀
Référence à propos de Python 3
str
modification: stackoverflow.com/questions/25898733/....OriginalL'auteur Eric O Lebigot
Il est également évident que
3.3 * 2.0
est numériquement identique à6.6
. Le dernier calcul n'est rien de plus que d'une augmentation de l'exposant binaire comme c'est le résultat d'une multiplication par une puissance de deux. Vous pouvez les voir dans la suite de:Ci-dessus vous voyez la représentation binaire des nombres en virgule flottante
3.3
et6.6
. La seule différence entre les deux chiffres est l'exposant, car ils ne sont multipliés par deux. Nous savons que la norme IEEE-754:2^53
exactement (pour binary64)Depuis
2.0
est exactement représentable, une multiplication avec ce numéro sera rien de plus qu'un changement dans l'exposant. Donc tout ce qui suit va créer le même nombres à virgule flottante:Est-ce à dire que
2.2*3.0
est différente de6.6
en raison de l'important? Non, c'était juste à cause des erreurs d'arrondi dans la multiplication.Un exemple où il aurait travaillé aurait été
5.5*2.0 == 2.2*5.0 == 11.0
. Ici, l'arrondissement a été favorableOriginalL'auteur kvantour