Quelle est la différence entre «mod» et «reste»?


133

Mon ami a dit qu'il y avait des différences entre "mod" et "reste".

Si oui, quelles sont ces différences en C et C ++? Est-ce que «%» signifie «mod» ou «rem» en C?


2
Il est probablement mal défini pour les opérandes négatifs.
Basile Starynkevitch

1
Je ne suis pas une personne C: (je ne peux donc pas vraiment répondre à cette question dans la boîte de réponse. Mais s'il vous plaît jeter un oeil à cet article :)
bonCodigo

1
% est le reste. Répondez aux détails ici -> blogs.msdn.com/b/ericlippert/archive/2011/12/05/…
wim

1
La question ne signifie rien tant que vous ne définissez pas précisément ce que signifient les termes.
David Heffernan

14
@David: la question porte sur la signification des termes. Si vous dites que la question n'a pas de sens, bien que plusieurs personnes la comprennent de la manière dont l'intervenant l'a voulu, alors je pense que vous devez être plus précis ce que vous entendez par le mot «signifie» ;-)
Steve Jessop

Réponses:


140

Il y a une différence entre le module et le reste. Par exemple:

-21mod 4est 3parce que -21 + 4 x 6c'est 3.

Mais -21divisé par 4donne -5avec un reste de -1.

Pour les valeurs positives, il n'y a pas de différence.


22
% signifie rem en C.
banuj

22
@Jinxiao: en C89, il était défini par l'implémentation: %c'était toujours le reste, mais cela pouvait aussi être le module (c'est-à-dire toujours positif), car en C89, la division entière était autorisée à arrondir vers l'infini négatif au lieu de 0. Donc, en C89, -5 / 2pourrait être -2avec reste -1, ou -3avec reste 1, la mise en œuvre devait simplement documenter qui. C99 a supprimé la flexibilité, donc maintenant -5 / 2est toujours -2.
Steve Jessop

2
En fait, le module n'est pas clair. Il semble y avoir de nombreuses définitions différentes, selon le contexte et la langue. Voir l'article de wikipedia sur modulo_operation. Dans certains contextes, c'est en fait la même chose que le reste.
Rudy Velthuis

9
Quelqu'un peut-il expliquer les étapes du premier calcul? Comment est le -21mod ? Pourquoi le calcul est-il ? 43-21 + 4 x 6
Oz Edri

13
@OzEdri Pour obtenir un certain nombre mod 4, vous ajoutez le multiple entier de 4 qu'il faut pour obtenir un nombre entre 0 et 3. Pour -21, cet entier est 6 car il -21 + 4 x 6est compris entre 0 et 3.
David Schwartz

47

Est-ce que «%» signifie «mod» ou «rem» en C?

En C, %le reste est 1 .

..., le résultat de l' /opérateur est le quotient algébrique avec toute partie fractionnaire rejetée ... (Ceci est souvent appelé "troncature vers zéro".) C11dr §6.5.5 6

Les opérandes de l' %opérateur doivent être de type entier. C11dr §6.5.5 2

Le résultat de l' /opérateur est le quotient de la division du premier opérande par le second; le résultat de l' %opérateur est le reste ... C11dr §6.5.5 5


Quelle est la différence entre «mod» et «reste»?

C ne définit pas "mod", comme la fonction de module entier utilisé dans la division euclidienne ou autre modulo . «Mod euclidien» diffère de l' a%bopération de C lorsqu'il aest négatif.

 // a % b
 7 %  3 -->  1  
 7 % -3 -->  1  
-7 %  3 --> -1  
-7 % -3 --> -1   

Modulo comme division euclidienne

 7 modulo  3 -->  1  
 7 modulo -3 -->  1  
-7 modulo  3 -->  2  
-7 modulo -3 -->  2   

Code modulo candidat:

int modulo_Euclidean(int a, int b) {
  int m = a % b;
  if (m < 0) {
    // m += (b < 0) ? -b : b; // avoid this form: it is UB when b == INT_MIN
    m = (b < 0) ? m - b : m + b;
  }
  return m;
}

Remarque sur la virgule flottante double fmod(double x, double y):, même si elle est appelée "fmod", ce n'est pas la même chose que la division euclidienne "mod", mais similaire au reste entier C:

Les fmod fonctions calculent le reste en virgule flottante de x/y. C11dr §7.12.10.1 2

fmod( 7,  3) -->  1.0  
fmod( 7, -3) -->  1.0  
fmod(-7,  3) --> -1.0  
fmod(-7, -3) --> -1.0   

Désambiguïsation : C a également une fonction nommée similaire double modf(double value, double *iptr)qui divise la valeur de l'argument en parties intégrales et fractionnaires, chacune ayant le même type et le même signe que l'argument. Cela n'a pas grand-chose à voir avec la discussion sur le "mod", sauf la similitude des noms.


1 Avant C99, la définition de C %était toujours le reste de la division, mais /permettait alors d'arrondir les quotients négatifs plutôt que la "troncature vers zéro". Voir Pourquoi obtenez-vous des valeurs différentes pour la division entière dans C89? . Ainsi, avec une compilation pré-C99, le %code peut agir exactement comme la division euclidienne "mod". Ce qui précède modulo_Euclidean()fonctionnera également avec ce reste de la vieille école alternative.


1
Pour implémenter la division euclidienne et les fonctions modulo en C, voir Division et module pour les informaticiens . Il peut courir plus vite si vous savez que seul votre dividende peut être négatif, mais votre diviseur est toujours positif: godbolt.org/g/63UqJo . En relation: une question asm x86 demandant un modulo non négatif
Peter Cordes

La définition habituelle de l'opérateur modulo ressemble plus à:
Mike Housky le

2

Le module, en arithmétique modulaire comme vous vous référez, est la valeur restante ou la valeur restante après la division arithmétique. Ceci est communément appelé reste. % est formellement l'opérateur de reste en C / C ++. Exemple:

7 % 3 = 1  // dividend % divisor = remainder

Ce qui reste à discuter est de savoir comment traiter les entrées négatives de cette opération%. Le C et le C ++ modernes produisent une valeur de reste signée pour cette opération où le signe du résultat correspond toujours à l'entrée de dividende sans tenir compte du signe de l'entrée de diviseur.


1

En C et C ++ et dans de nombreux langages, %le reste n'est PAS l'opérateur de module.

Par exemple, dans l'opération, -21 / 4la partie entière est -5et la partie décimale est -.25. Le reste est la partie fractionnaire multipliée par le diviseur, donc notre reste l'est -1. JavaScript utilise l'opérateur reste et le confirme

console.log(-21 % 4 == -1);

L'opérateur de module est comme si vous aviez une "horloge". Imaginez un cercle avec les valeurs 0, 1, 2 et 3 respectivement aux positions 12 heures, 3 heures, 6 heures et 9 heures. Les temps de quotient pas à pas dans le sens des aiguilles d'une montre nous amènent sur le résultat de notre opération de module, ou, dans notre exemple avec un quotient négatif, dans le sens inverse des aiguilles d'une montre, donnant 3.

Remarque: le module est toujours le même signe que le diviseur et reste le même signe que le quotient. Ajouter le diviseur et le reste lorsque le reste au moins un est négatif donne le module.


-2

En mathématiques, le résultat de l'opération modulo est le reste de la division euclidienne. Cependant, d'autres conventions sont possibles. Les ordinateurs et les calculatrices ont diverses manières de stocker et de représenter des nombres; ainsi, leur définition du fonctionnement modulo dépend du langage de programmation et / ou du matériel sous-jacent.

 7 modulo  3 -->  1  
 7 modulo -3 --> -2 
-7 modulo  3 -->  2  
-7 modulo -3 --> -1 

2
La division Euclidienne du wiki affirme 0 ≤ r < |b|ce qui signifie le reste aka "opération modulo". est toujours au moins égal à 0. Quelle définition utilisez-vous qui donne -2 et -1?
chux - Réintégrer Monica le

monsieur, je ne sais pas mais je viens de google 7 modulo -3 -> -2 .and.-7 modulo -3 -> -1 s'il vous plaît expliquer monsieur pourquoi cela s'est produit
shub sharma

1
Google utilise une définition différente de modulo (modulo signé?) De la division Euclidienne de Wiki (telle que décrite par Raymond T. Boute). Cela discute davantage les différences. Morale de l'histoire: a%bet a modulo bont le même sens quand elles a,bsont positives. C99 définit %précisément avec des valeurs négatives. C appelle cela "reste". "Modulo" a diverses définitions dans le monde concernant les valeurs négatives. C spec utilise uniquement "modulo" dans le contexte des nombres positifs.
chux - Réintégrer Monica
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.