c - son - suma de numeros negativos
Operación de módulo con números negativos (9)
Basado en la Especificación C99: a = (a / b) * b + a % b
Podemos escribir una función para calcular (a % b) = a - (a / b) * b
!
int remainder(int a, int b)
{
return a - (a / b) * b;
}
Para la operación del módulo, podemos tener la siguiente función (suponiendo que b> 0)
int mod(int a, int b)
{
int r = a % b;
return r < 0 ? r + b : r;
}
Mi conclusión es (a% b) en C es un operador de resto y no un operador de módulo.
En el programa de CA, estaba probando las siguientes operaciones (solo para verificar el comportamiento)
x = 5 % (-3);
y = (-5) % (3);
z = (-5) % (-3);
printf("%d ,%d ,%d", x, y, z);
me dio salida como (2, -2 , -2)
en gcc. Esperaba un resultado positivo todo el tiempo. ¿Puede un módulo ser negativo? ¿Alguien puede explicar este comportamiento?
C99 requiere que cuando a/b
sea representable:
(a/b) * b
+ a%b
será igual a
Esto tiene sentido, lógicamente. ¿Derecha?
Veamos a qué conduce esto:
Ejemplo A. 5/(-3)
es -1
=> (-1) * (-3)
+ 5%(-3)
= 5
Esto solo puede suceder si el 5%(-3)
es 2.
Ejemplo B. (-5)/3
es -1
=> (-1) * 3
+ (-5)%3
= -5
Esto solo puede suceder si (-5)%3
es -2
El operador %
en C no es el operador de módulo sino el operador restante .
Los operadores de módulo y resto difieren con respecto a los valores negativos.
Con un operador de resto, el signo del resultado es el mismo que el signo del dividendo, mientras que con un operador de módulo, el signo del resultado es el mismo que el del divisor.
C define la operación %
para a % b
como:
a == (a / b * b) + a % b
con /
la división entera con truncamiento hacia 0
. Ese es el truncamiento que se realiza hacia 0
(y no hacia la infinitud negativa) que define el %
como un operador de resto en lugar de un operador de módulo.
El operador de módulo da el resto. El operador de módulo en c generalmente toma el signo del numerador
- x = 5% (-3) - aquí el numerador es positivo, por lo tanto, resulta en 2
- y = (-5)% (3) - aquí el numerador es negativo, por lo tanto resulta -2
- z = (-5)% (-3) - aquí el numerador es negativo, por lo tanto resulta -2
También el operador de módulo (resto) solo se puede usar con el tipo entero y no se puede usar con coma flotante.
El operador de módulo es como el operador de mod cuando el número es positivo, pero diferente si el número es negativo.
Muchas veces en los problemas se nos pide que demos la respuesta modulo 10 ^ 9 + 7.
Deje que la respuesta (antes de usar módulo) se denote por ''a''.
Regla sencilla y directa
si a es positivo , entonces un módulo 10 ^ 9 + 7 = a% (10 ^ 9 + 7)
si a es negativo , entonces un módulo 10 ^ 9 + 7 = (a% (10 ^ 9 + 7)) + (10 ^ 9 + 7)
Si, en tales problemas, encontramos que cualquier paso del ciclo puede calcular un valor que está fuera del rango entero (si estamos usando enteros), entonces podemos usar el operador de módulo en ese paso en sí. La respuesta final será como si hubiéramos usado el operador de módulo solo una vez.
Esto es porque- (a * b)% c = ((a% c) (b% c))% c Lo mismo vale para sumar y restar.
El resultado de la operación Modulo depende del signo del numerador, y por lo tanto obtienes -2 para y y z
Aquí está la referencia
http://www.chemie.fu-berlin.de/chemnet/use/info/libc/libc_14.html
División entera
Esta sección describe las funciones para realizar la división de enteros. Estas funciones son redundantes en la biblioteca GNU C, ya que en GNU C el operador ''/'' siempre se redondea hacia cero. Pero en otras implementaciones de C, ''/'' puede redondear de manera diferente con argumentos negativos. div y ldiv son útiles porque especifican cómo redondear el cociente: hacia cero. El resto tiene el mismo signo que el numerador.
En Matemáticas, de donde surgen estas convenciones, no hay ninguna afirmación de que la aritmética de módulo deba arrojar un resultado positivo.
P.ej.
1 mod 5 = 1, pero también puede ser igual a -4. Es decir, 1/5 produce un resto 1 de 0 o -4 de 5. (Ambos factores de 5)
Del mismo modo, -1 mod 5 = -1, pero también puede ser igual a 4. Es decir, -1/5 produce un resto -1 de 0 o 4 de -5. (Ambos factores de 5)
Para más información, busque en las clases de equivalencia en Matemáticas.
Las otras respuestas han explicado en C99 o posterior, la división de enteros que involucran operandos negativos siempre se trunca hacia cero .
Tenga en cuenta que, en C89 , si el resultado redondeado hacia arriba o hacia abajo está definido por la implementación. Como (a/b) * b + a%b
es igual a a
en todos los estándares, el resultado de %
involucra operandos negativos también se define en la implementación en C89.
No creo que haya ninguna necesidad de verificar si el número es negativo. La función general más simple para encontrar el módulo positivo sería esta: funcionaría en los valores positivos y negativos de x.
int modulo(int x,int N){
return (x % N + N) %N;
}