¿Cuál es la diferencia entre "mod" y "resto"?

133

Mi amigo dijo que hay diferencias entre "mod" y "resto".

Si es así, ¿cuáles son esas diferencias en C y C ++? ¿'%' Significa "mod" o "rem" en C?

songhir
fuente
2
Probablemente esté mal definido para operandos negativos.
Basile Starynkevitch
1
No soy una persona C :( así que no puedo responder a esta dentro del cuadro de respuesta, pero por favor, eche un vistazo a esto. Artículo :)
bonCodigo
1
% es resto. Responda los detalles aquí -> blogs.msdn.com/b/ericlippert/archive/2011/12/05/…
wim
1
La pregunta no significa nada hasta que defina con precisión el significado de los términos.
David Heffernan
14
@David: la pregunta es sobre el significado de los términos. Si dice que la pregunta no tiene sentido, a pesar de que varias personas la entienden de la manera que pretendía el interrogador, entonces creo que debe ser más específico lo que quiere decir con la palabra "mean" ;-)
Steve Jessop

Respuestas:

140

Hay una diferencia entre módulo y resto. Por ejemplo:

-21mod 4es 3porque -21 + 4 x 6es 3.

Pero -21dividido por 4da -5con un resto de -1.

Para valores positivos, no hay diferencia.

David Schwartz
fuente
22
% significa rem en C.
banuj
22
@Jinxiao: en C89 fue definido por la implementación: %siempre era el resto, pero podría también ser el módulo (es decir, siempre positivo), porque en C89 número entero división se le permitió ronda hacia el infinito negativo en lugar de hacia 0. Por lo tanto en C89, -5 / 2podría ser -2con el resto -1, o -3con el resto 1, la implementación solo tenía que documentar qué. C99 eliminó la flexibilidad, por lo que ahora -5 / 2es siempre -2.
Steve Jessop
2
En realidad, no está claro qué módulo es. Parece que hay muchas definiciones diferentes, dependiendo del contexto y el idioma. Vea el artículo de wikipedia sobre modulo_operation. En algunos contextos, en realidad es lo mismo que el resto.
Rudy Velthuis
9
¿Alguien puede explicar los pasos en el primer cálculo? ¿Cómo es el -21mod ? ¿Por qué es el cálculo ? 43-21 + 4 x 6
Oz Edri
13
@OzEdri Para obtener un número 4, agregue cualquier número entero múltiplo de 4 que se necesita para obtener un número entre 0 y 3. Para -21, ese número entero es 6 porque -21 + 4 x 6está entre 0 y 3.
David Schwartz
47

¿'%' Significa "mod" o "rem" en C?

En C, %es el resto 1 .

..., el resultado del /operador es el cociente algebraico con cualquier parte fraccional descartada ... (Esto a menudo se llama "truncamiento hacia cero".) C11dr §6.5.5 6

Los operandos del %operador deberán tener un tipo entero. C11dr §6.5.5 2

El resultado del /operador es el cociente de la división del primer operando por el segundo; el resultado del %operador es el resto ... C11dr §6.5.5 5


¿Cuál es la diferencia entre "mod" y "resto"?

C no define "mod", como la función de módulo entero utilizada en la división euclidiana u otro módulo . El "mod euclidiano" difiere de la a%boperación de C cuando aes negativo.

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

Módulo como división euclidiana

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

Código de módulo candidato:

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;
}

Nota sobre el punto flotante: double fmod(double x, double y)aunque se llama "fmod", no es lo mismo que la división euclidiana "mod", pero es similar al resto del entero C:

Las fmod funciones calculan el resto de coma flotante 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   

Desambiguación : C también tiene una función con nombre similar double modf(double value, double *iptr)que divide el valor del argumento en partes integrales y fraccionarias, cada una de las cuales tiene el mismo tipo y signo que el argumento. Esto tiene poco que ver con la discusión "mod" aquí, excepto la similitud de nombres.


1 Antes de C99, la definición de C %todavía era el resto de la división, pero /permitía redondear los cocientes negativos en lugar de "truncar hacia cero". Consulte ¿Por qué obtiene valores diferentes para la división de enteros en C89? . Por lo tanto, con alguna compilación anterior a C99, el %código puede actuar como el "mod" de la división euclidiana. Lo anterior modulo_Euclidean()también funcionará con este resto alternativo de la vieja escuela.

chux - Restablece a Monica
fuente
1
Para implementar la división euclidiana y las funciones de módulo en C, vea División y módulo para informáticos . Puede ejecutarse más rápido si sabe que su dividendo puede ser negativo, pero su divisor siempre es positivo: godbolt.org/g/63UqJo . Relacionado: una pregunta x86 asm pidiendo un módulo no negativo
Peter Cordes
La definición habitual del operador de módulo es más como:
Mike Housky
2

Módulo, en aritmética modular como se refiere, es el valor restante o el valor restante después de la división aritmética. Esto se conoce comúnmente como resto. % es formalmente el operador restante en C / C ++. Ejemplo:

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

Lo que queda por debatir es cómo tratar las entradas negativas para esta operación%. C y C ++ modernos producen un valor de resto con signo para esta operación donde el signo del resultado siempre coincide con la entrada de dividendos sin tener en cuenta el signo de la entrada del divisor.

usuario487158
fuente
1

En C y C ++ y muchos lenguajes, %el resto NO es el operador del módulo.

Por ejemplo, en la operación, -21 / 4la parte entera es -5y la parte decimal es -.25. El resto es la fracción parcial multiplicada por el divisor, por lo que nuestro resto es -1. JavaScript utiliza el operador restante y confirma esto

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

El operador del módulo es como si tuvieras un "reloj". Imagine un círculo con los valores 0, 1, 2 y 3 en las posiciones de las 12 en punto, las 3 en punto, las 6 en punto y las 9 en punto, respectivamente. Pasar el cociente veces alrededor del reloj en el sentido de las agujas del reloj nos lleva al resultado de nuestra operación de módulo, o, en nuestro ejemplo con un cociente negativo, en sentido antihorario, dando 3.

Nota: el módulo es siempre el mismo signo que el divisor y el resto el mismo signo que el cociente. Agregar el divisor y el resto cuando el resto al menos uno es negativo produce el módulo.

theEpsilon
fuente
-2

En matemáticas, el resultado de la operación de módulo es el resto de la división euclidiana. Sin embargo, otras convenciones son posibles. Las computadoras y las calculadoras tienen varias formas de almacenar y representar números; por lo tanto, su definición de la operación del módulo depende del lenguaje de programación y / o del hardware subyacente.

 7 modulo  3 -->  1  
 7 modulo -3 --> -2 
-7 modulo  3 -->  2  
-7 modulo -3 --> -1 
shub sharma
fuente
2
La división wiki Euclidiana afirma 0 ≤ r < |b|que significa el resto también conocido como "operación de módulo". siempre es al menos 0. ¿Qué definición estás usando que da como resultado -2 y -1?
chux - Restablecer Monica
señor, no, pero solo busco google 7 módulo -3 -> -2 .and.-7 módulo -3 -> -1 por favor explique señor por qué sucedió esto
shub sharma
1
Google utiliza una definición diferente de módulo (¿módulo con signo?) Que la división Wiki Euclidiana (como lo describe Raymond T. Boute). Esto discute más las diferencias. Moraleja de la historia: a%by a modulo btienen el mismo significado cuando a,bson positivos. C99 define %con precisión con valores negativos. C llama a este "resto'. 'Modulo' tiene varias definiciones en el mundo en relación con los valores negativos C spec sólo utiliza. 'Módulo' en el contexto de los números positivos.
Chux - Restablecer Monica