Question

Pouvez-vous s'il vous plaît me dire combien coûte (-2) % 5?Selon mon interpréteur Python, c'est 3, mais avez-vous une explication judicieuse à cela ?

J'ai lu que dans certaines langues, le résultat peut dépendre de la machine, mais je n'en suis pas sûr.

Était-ce utile?

La solution

D'ailleurs:la plupart des langages de programmation ne seraient pas d'accord avec Python et donneraient le résultat -2.Selon l'interprétation du module, cela est correct.Cependant, la définition mathématique la plus acceptée stipule que le module de un et b est le reste (strictement positif) r de la division de un / b.Plus précisément, 0 <= r < b par définition.

Autres conseils

Le résultat de l'opération de module sur les négatifs semble dépendre du langage de programmation et voici une liste http://en.wikipedia.org/wiki/Modulo_operation

Votre interpréteur Python est correct.Une façon (stupide) de calculer un module consiste à soustraire ou à ajouter le module jusqu'à ce que la valeur résultante soit comprise entre 0 et (module − 1).

par exemple.:13 mod 5 = (13 − 5) mod 5 = (13 − 10) mod 5 = 3

ou dans votre cas :−2 mod 5 = (−2 + 5) mod 5 = 3

Comme le dit la documentation dans Opérations arithmétiques binaires, Python assure que :

Les opérateurs de division entière et modulo sont reliés par l'identité suivante : x == (x/y)*y + (x%y).La division entière et le modulo sont également connectés à la fonction intégrée divmod() : divmod(x, y) == (x/y, x%y).

Et vraiment,

>>> divmod(-2, 5)
(-1, 3).

Une autre façon de visualiser l’uniformité de cette méthode est de calculer divmod pour une petite séquence de nombres :

>>> for number in xrange(-10, 10):
...     print divmod(number, 5)
...
(-2, 0)
(-2, 1)
(-2, 2)
(-2, 3)
(-2, 4)
(-1, 0)
(-1, 1)
(-1, 2)
(-1, 3)
(-1, 4)
(0, 0)
(0, 1)
(0, 2)
(0, 3)
(0, 4)
(1, 0)
(1, 1)
(1, 2)
(1, 3)
(1, 4)

Eh bien, 0 % 5 devrait être 0, n'est-ce pas ?

-1 % 5 devrait être 4 car c'est le prochain chiffre autorisé dans le sens inverse (c'est-à-dire qu'il ne peut pas être 5, car il est hors de portée).

Et selon cette logique, -2 doit être 3.

La façon la plus simple de penser à la façon dont cela fonctionnera est de continuer à ajouter ou à soustraire 5 jusqu'à ce que le nombre se situe entre 0 (inclus) et 5 (exclus).

Je ne suis pas sûr de la dépendance à la machine - je n'ai jamais vu une telle implémentation, mais je ne peux pas dire que cela n'a jamais été fait.

Comme expliqué dans d'autres réponses, il existe de nombreux choix pour une opération modulo avec des valeurs négatives.En général, différents langages (et différentes architectures de machines) donneront un résultat différent.

Selon le Manuel de référence Python,

L'opérateur modulo donne toujours un résultat avec le même signe que son deuxième opérande (ou zéro) ;la valeur absolue du résultat est strictement inférieure à la valeur absolue du deuxième opérande.

est le choix fait par Python.Fondamentalement, modulo est défini de telle sorte que cela soit toujours valable :

x == (x/y)*y + (x%y)

il est donc logique que (-2)%5 = -2 - (-2/5)*5 = 3

Eh bien, -2 divisé par 5 serait 0 avec un reste de 3.Je ne pense pas que cela devrait dépendre beaucoup de la plate-forme, mais j'ai vu des choses plus étranges.

Il est bien 3.Dans Arithmétique modulaire, un module est simplement le reste d'une division, et le reste de -2 divisé par 5 est 3.

Le résultat dépend de la langue.Python renvoie le signe du diviseur, où par exemple c# renvoie le signe du dividende (c'est-à-dire.-2 % 5 renvoie -2 en c#).

Une explication pourrait être que les nombres négatifs sont stockés en utilisant complément à 2.Lorsque l'interpréteur Python tente d'effectuer l'opération modulo, il la convertit en valeur non signée.En tant que tel, au lieu de faire (-2) % 5, il calcule en fait 0xFFFF_FFFF_FFFF_FFFD % 5 qui vaut 3.

Attention à ne pas vous fier à ce comportement de mod en C/C++ sur tous les OS et architectures.Si je me souviens bien, j'ai essayé de m'appuyer sur du code C/C++ comme

float x2 = x % n;

pour garder x2 dans la plage de 0 à n-1, mais des nombres négatifs se sont glissés lorsque je compilais sur un système d'exploitation, mais les choses fonctionneraient bien sur un autre système d'exploitation.Cela a rendu le débogage très compliqué puisque cela ne se produisait que la moitié du temps !

Il semble y avoir une confusion courante entre les termes « modulo » et « reste ».

En mathématiques, un reste devrait toujours être défini de manière cohérente avec le quotient, de sorte que si a / b == c rem d alors (c * b) + d == a.Selon la façon dont vous arrondissez votre quotient, vous obtenez des restes différents.

Cependant, modulo devrait toujours donner un résultat 0 <= r < divisor, ce qui n'est cohérent avec la division arrondie à moins l'infini que si vous autorisez les entiers négatifs.Si la division arrondit vers zéro (ce qui est courant), modulo et reste ne sont équivalents que pour les valeurs non négatives.

Certains langages (notamment C et C++) ne définissent pas les comportements d'arrondi/reste requis et % c'est ambigu.Beaucoup définissent l'arrondi vers zéro, mais utilisent le terme modulo où le reste serait plus correct.Python est relativement inhabituel dans la mesure où il arrondit à l'infini négatif, donc modulo et reste sont équivalents.

Ada se rapproche de zéro IIRC, mais a les deux mod et rem les opérateurs.

La politique C est destinée à permettre aux compilateurs de choisir l'implémentation la plus efficace pour la machine, mais l'OMI est une fausse optimisation, du moins de nos jours.Un bon compilateur sera probablement capable d'utiliser l'équivalence pour l'optimisation partout où un nombre négatif ne peut pas apparaître (et presque certainement si vous utilisez des types non signés).D'un autre côté, lorsque des nombres négatifs peuvent apparaître, vous vous souciez presque certainement des détails - pour des raisons de portabilité, vous devez utiliser des algorithmes et/ou des contrôles surcomplexes très soigneusement conçus pour garantir que vous obtenez les résultats souhaités, quels que soient l'arrondi et le reste. comportement.

En d’autres termes, le gain de cette « optimisation » est pour la plupart (sinon toujours) une illusion, alors qu’il y a des coûts bien réels dans certains cas – c’est donc une fausse optimisation.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top