64 votes

C, Python - comportement différent de l'opération modulo (%)

J'ai constaté que la même opération mod produisait des résultats différents selon la langue utilisée.

En Python:

 -1 % 10
 

produit 9

En C il produit -1 !

1) Lequel est le bon modulo?
2) Comment faire en sorte que l'opération de mod en C soit la même que celle en Python?

70voto

Alex B Points 34304
  1. Les deux variantes sont correctes, cependant en mathématiques (la théorie des nombres en particulier), le modulo de Python est le plus couramment utilisé.
  2. En C, vous faites ((n % M) + M) % M pour obtenir le même résultat qu'en Python. Par exemple. ((-1 % 10) + 10) % 10 . Notez que cela fonctionne toujours pour les entiers positifs: ((17 % 10) + 10) % 10 == 17 % 10 , ainsi que pour les deux variantes de mise en œuvre de C (reste positif ou négatif).

31voto

fortran Points 26495

Python a une "vraie" opération modulo, alors que C a une opération restante .

Il a une relation directe avec la manière dont la division entière négative est gérée, c'est-à-dire arrondie vers 0 ou moins l'infini. Python arrondit vers moins infini et C (99) vers 0, mais dans les deux langues (n/m)*m + n%m == n , l'opérateur% doit donc compenser dans la bonne direction.

Ada est plus explicite et a les deux, comme mod et rem .

16voto

AndreyT Points 139512

En C89/90 le comportement de l'opérateur de division et le reste de l'opérateur négatif des opérandes est de la mise en œuvre définies, ce qui signifie qu'en fonction de l'application, vous pouvez obtenir soit le comportement. Il est juste nécessaire que les opérateurs s'accordent les uns avec les autres: de l' a / b = q et a % b = r suit a = b * q + r. Utilisation statique affirme, dans votre code pour vérifier le comportement, si elle se fait de façon critique sur le résultat.

En C99 le comportement que vous observez est devenu un standard.

En effet, les comportements ont certaine logique à cela. Le Python comportement met en œuvre le vrai modulo. Le comportement observé est C est cohérente avec l'arrondi vers 0 (c'est aussi le Fortran comportement).

L'une des raisons de l'arrondi vers 0 est préféré à C, c'est qu'il est assez naturel de s'attendre à la suite de l' -a / b être le même que -(a / b). En cas de vrai modulo comportement, -1 % 10 permettrait d'évaluer à 9, ce qui signifie qu' -1 / 10 a à -1. Cela peut sembler peu naturelle, depuis -(1 / 10) est de 0.

5voto

Brian R. Bondy Points 141769

Les deux réponses sont correctes, depuis -1 modulo 10 est le même que 9 modulo 10.

r = (a mod m)
a = n*q + r

Vous pouvez être sûr qu' |r| < |n|,, mais pas ce que la valeur de r est. Il y a 2 réponses, négatives et positives.


En C89, bien que la réponse sera toujours la bonne, la valeur exacte d'un modulo (ils se réfèrent à lui comme le reste) n'est pas défini, le sens qu'il peut être soit un résultat négatif ou un résultat positif. En C99 le résultat est défini.

Si vous souhaitez que la réponse est positive, vous pouvez simplement ajouter 10 si vous trouvez que votre réponse est négative.

Pour obtenir le modulo à l'opérateur de travailler de la même manière sur toutes les langues, rappelez-vous que:

n mod M == (n + M) mod M

et en général:

n mod M == (n + X * M) mod M

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X