Operación de módulo con números negativos

Resuelto Alva asked hace 12 años • 0 respuestas

En un programa en C estaba probando las siguientes operaciones (solo para comprobar el comportamiento)

 x = 5 % (-3);
 y = (-5) % (3);
 z = (-5) % (-3); 

printf("%d ,%d ,%d", x, y, z); 

Me dio resultados como (2, -2 , -2)en gcc. Esperaba siempre un resultado positivo. ¿Puede un módulo ser negativo? ¿Alguien puede explicar este comportamiento?

Alva avatar Jul 30 '12 18:07 Alva
Aceptado

C99 requiere que cuando a/bsea representable:

(a/b) * b + a%b será iguala

Esto tiene sentido, lógicamente. ¿Bien?

Veamos a qué conduce esto:


El ejemplo A. 5/(-3)es-1

=> (-1) * (-3) + 5%(-3) =5

Esto sólo puede suceder si 5%(-3)es 2.


El ejemplo B. (-5)/3es-1

=> (-1) * 3 + (-5)%3 =-5

Esto sólo puede suceder si (-5)%3es-2

ArjunShankar avatar Jul 30 '2012 11:07 ArjunShankar

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 (numerador) mientras que con un operador de módulo el signo del resultado es el mismo que el del divisor (denominador).

C define la %operación para a % bcomo:

  a == (a / b * b) + a % b

con /la división de enteros con truncamiento hacia 0. Ese es el truncamiento que se realiza hacia 0(y no hacia el infinito negativo) que define a %como un operador de resto en lugar de un operador de módulo.

ouah avatar Jul 30 '2012 11:07 ouah

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 de módulo, podemos tener la siguiente función (asumiendo b > 0)

int mod(int a, int b)
{
    int r = a % b;
    return r < 0 ? r + b : r;
}

Mi conclusión es que a % ben C es una operación de resto y NO una operación de módulo.

dewang avatar Oct 10 '2013 06:10 dewang

No creo que no sea necesario comprobar si el número es negativo.

Una función simple para encontrar el módulo positivo sería esta:

Editar: asumiendo N > 0yN + N - 1 <= INT_MAX

int modulo(int x,int N){
    return (x % N + N) %N;
}

Esto funcionará tanto para valores positivos como negativos de x.

PD original: también como lo señaló @chux, si su x y N pueden alcanzar algo como INT_MAX-1 e INT_MAX respectivamente, simplemente reemplácelo intcon long long int.

Y si también cruzan límites largos (es decir, cerca de LLONG_MAX), deberá manejar los casos positivos y negativos por separado como se describe en otras respuestas aquí.

Udayraj Deshmukh avatar Feb 09 '2017 08:02 Udayraj Deshmukh