J'essayais de normaliser un ensemble de nombres compris entre -100, 0 et 0 à 10-100. J'avais des problèmes seulement pour constater que même sans aucune variable, cela n'évalue pas la manière dont je m'attendais:
>>> (20-10) / (100-10)
0
La division flottante ne fonctionne pas non plus:
>>> float((20-10) / (100-10))
0.0
Si l'un des côtés de la division est transformé en float, cela fonctionnera:
>>> (20-10) / float((100-10))
0.1111111111111111
Chaque partie du premier exemple est évaluée en tant qu'int, ce qui signifie que la réponse finale sera convertie en int. Étant donné que 0,111 est inférieur à 0,5, il est arrondi à 0. À mon avis, ce n'est pas transparent, mais je suppose que c'est comme ça.
Quelle est l'explication?
Vous utilisez Python 2.x, où les divisions entières seront tronquées au lieu de devenir un nombre à virgule flottante.
>>> 1 / 2
0
Vous devriez en faire une variable float
:
>>> float(10 - 20) / (100 - 10)
-0.1111111111111111
ou from __future__ import division
, ce qui oblige /
à adopter le comportement de Python 3.x qui renvoie toujours un float.
>>> from __future__ import division
>>> (10 - 20) / (100 - 10)
-0.1111111111111111
Vous mettez en intégrant des nombres entiers afin que Python vous rende un entier :
>>> 10 / 90
0
Si ensuite vous arrondissez ceci à un float, l'arrondi aura déjà été fait, autrement dit, 0 entier deviendra toujours 0 float.
Si vous utilisez des flottants de part et d'autre de la division, Python vous donnera la réponse à laquelle vous vous attendez.
>>> 10 / 90.0
0.1111111111111111
Donc dans votre cas:
>>> float(20-10) / (100-10)
0.1111111111111111
>>> (20-10) / float(100-10)
0.1111111111111111
Vous devez le changer en float AVANT de faire la division. C'est:
float(20 - 10) / (100 - 10)
Cela a à voir avec la version de python que vous utilisez. Fondamentalement, il adopte le comportement C: si vous divisez deux nombres entiers, les résultats seront arrondis à un nombre entier inférieur. N'oubliez pas non plus que Python effectue les opérations de gauche à droite, ce qui joue un rôle lors de la conversion.
Exemple: Puisqu'il s'agit d'une question qui me vient toujours à l'esprit lorsque je fais des opérations arithmétiques (si je devrais convertir en float et quel nombre), un exemple de cet aspect est présenté:
>>> a = 1/2/3/4/5/4/3
>>> a
0
Lorsque nous divisons des nombres entiers, il n’est pas surprenant que les valeurs arrondies soient inférieures.
>>> a = 1/2/3/4/5/4/float(3)
>>> a
0.0
Si nous transtypons le dernier entier à float, nous aurons toujours zéro, car au moment où notre nombre est divisé par le float, il est déjà devenu 0 à cause de la division entière.
>>> a = 1/2/3/float(4)/5/4/3
>>> a
0.0
Même scénario que ci-dessus, mais déplacement de la conversion de type float un peu plus près du côté gauche.
>>> a = float(1)/2/3/4/5/4/3
>>> a
0.0006944444444444445
Enfin, lorsque nous transtypons le premier nombre entier à float, le résultat obtenu est celui souhaité, puisqu’à partir de la première division, c’est-à-dire la plus à gauche, nous utilisons des flottants.
Extra 1: Si vous essayez de répondre à cela pour améliorer l’évaluation arithmétique, vous devriez vérifier this
Extra 2: Faites attention au scénario suivant:
>>> a = float(1/2/3/4/5/4/3)
>>> a
0.0
Dans Python 2.7, l'opérateur /
est une division entière si les entrées sont des entiers:
>>>20/15
1
>>>20.0/15.0
1.33333333333
>>>20.0/15
1.33333333333
Dans Python 3.3, l'opérateur /
est une division flottante même si les entrées sont des entiers.
>>> 20/15
1.33333333333
>>>20.0/15
1.33333333333
Pour la division entière en Python 3, nous utiliserons l'opérateur //
.
L'opérateur //
est un opérateur de division entier dans Python 2.7 et Python 3.3.
En Python 2.7 et Python 3.3:
>>>20//15
1
Maintenant, voir la comparaison
>>>a = 7.0/4.0
>>>b = 7/4
>>>print a == b
Pour le programme ci-dessus, la sortie sera False en Python 2.7 et True en Python 3.3.
En Python 2.7 a = 1.75 et b = 1.
En Python 3.3, a = 1,75 et b = 1,75, simplement parce que /
est une division float.
Spécifier un float en plaçant un '.' après que le nombre le fera également flotter par défaut.
>>> 1 / 2
0
>>> 1. / 2.
0.5
Faites en sorte qu'au moins l'un d'eux flotte, alors ce sera une division flottante, pas un entier
>>> (20.0-10) / (100-10)
0.1111111111111111
Lancer le résultat en flottant est trop tard.
En python cv2
non mis à jour le calcul de la division. donc, vous devez inclure from __future__ import division
en première ligne du programme.
Personnellement, j'ai préféré insérer un 1. *
au tout début. Donc, l'expression devient quelque chose comme ceci:
1. * (20-10) / (100-10)
Comme je fais toujours une division pour une formule comme:
accuracy = 1. * (len(y_val) - sum(y_val)) / len(y_val)
il est donc impossible d'ajouter simplement un .0
comme 20.0
. Et dans mon cas, emballer avec float()
risque de perdre un peu de lisibilité.
De toute façon, c'est la division entière. 10/90 = 0. Dans le second cas, vous transcrivez simplement 0 en float.
Essayez de convertir l’un des opérandes de "/" en float:
float(20-10) / (100-10)
Vous lancez un flottement après la division dans votre deuxième exemple. Essaye ça:
float(20-10) / float(100-10)
Je suis un peu surpris que personne n'ait mentionné que l'affiche originale aurait peut-être souhaité que les nombres rationnels résultent. Si cela vous intéresse, le programme basé sur Python Sage vous soutient . (Actuellement, toujours basé sur Python 2.x, bien que 3.x soit en cours.)
sage: (20-10) / (100-10)
1/9
Ce n'est pas une solution pour tout le monde, car il effectue certaines opérations de préparification de sorte que ces nombres ne sont pas des int
s, mais des éléments de classe Sage Integer
. Cela vaut néanmoins la peine d’être mentionné dans l’écosystème Python.