web-dev-qa-db-fra.com

Quelle est la différence entre "mod" et "reste"?

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

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

106
songhir

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

-21 mod 4 est 3 car -21 + 4 x 6 est 3.

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

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

111
David Schwartz

Est-ce que '%' signifie "mod" ou "rem" en C?

En C, % est le reste1.

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

Les opérandes de l'opérateur % doivent avoir un 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", tel que la fonction de module entier utilisée dans division euclidienne ou autre modulo . "Euclidean mod" diffère de l'opération a%b de C lorsque a est négatif.

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

Modulo en tant que 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 à propos de la virgule flottante: double fmod(double x, double y), même si elle est appelée "fmod", n’est pas identique à la division euclidienne "mod", mais similaire au reste de l’entier C:

Les fonctions fmod 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   

Disambiguation : C possède é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 d’elles ayant le même type et le même signe que l’argument. Cela a peu à voir avec la discussion "mod" ici sauf similitude de nom.


1 Avant C99, la définition de % par C était toujours le reste de la division. Cependant, / permettait alors aux quotients négatifs d'arrondir vers le bas plutôt que "la troncature vers zéro". Voir Pourquoi obtenez-vous différentes valeurs pour la division entière dans C89? . Ainsi, avec certaines compilations antérieures à C99, le code % peut agir comme la division euclidienne "mod". Le modulo_Euclidean() ci-dessus fonctionnera également avec ce reste de la vieille école.

32
chux

Le module, en arithmétique modulaire, est la valeur qui reste ou qui reste après la division arithmétique. Ceci est communément appelé reste. % est formellement l'opérateur restant en C/C++. Exemple:

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

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

3
user487158