Operaciones Modulo en Programación con Resultados Negativos

En programación, la operación de módulo da el resto o el resto con signo de una división, después de que un número entero se divide por otro número entero. Es uno de los operadores más utilizados en programación . Este artículo analiza cuándo y por qué la operación de módulo arroja un resultado negativo.

Ejemplos:

  • En C , 3 % 2 devuelve 1 . Sin embargo, -3 % 2 es -1 y 3 % -2 da 1 .
  • En Python , -3%2 es 1 y 3%-2 es -1 .

Por lo tanto, es evidente que la misma expresión de -3 % 2 da resultados diferentes en diferentes lenguajes de programación. Este resultado está más relacionado con las matemáticas que con la programación. Las matemáticas mencionadas aquí ayudarán a comprender las preguntas un poco más fácilmente. 
Para entender por qué sucede esto, se necesita un poco de conocimiento sobre la división euclidiana y algunos puntos relacionados con la aritmética modular .

División euclidiana :En aritmética,división euclidianao división con resto es el proceso de dividir un número entero (el dividendo) por otro (el divisor), de tal forma que se obtiene un cociente y el resto es menor que el divisor.

Dados dos enteros a y b (donde b ≠ 0 ), existen enteros únicos q y r tales que:

a = bq + r ( 0 ≤ r < |b|
donde, |b| denota el valor absoluto de b .

En la ecuación anterior, cada uno de los cuatro enteros tiene su propio nombre, es decir,

  • a se llama dividendo .
  • b se llama divisor .
  • q se llama el cociente .
  • r se llama resto .

Por ejemplo:

  • Si a = 9 y b = 4, entonces q = 2 y r = 1, ya que 9 = 4 × 2 + 1.
  • Si a = -9 y b = 4, entonces q = -3 y r = 3, ya que -9 = 4 × -3 + 3.
  • Si a = 9 y b = -4, entonces q = -2 y r = 1, ya que 9 = -4 × -2 + 1.
  • Si a = -9 y b = -4, entonces q = 3 y r = 3, ya que -9 = -4 × 3 + 3.

Explicaciones de los ejemplos anteriores:

  • El primer ejemplo se explica por sí mismo ya que 9/4 da cociente 2 y resto 1.
  • El segundo ejemplo (-9/4) da cociente -3 y no -2 . Esto sucede porque si tomamos -2 como cociente entonces -9 = 4 × -2 + (-1) . Se genera un resto de -1 que no cumple las condiciones de la división euclidiana . No hace que -9/4 = -2 sea incorrecto, simplemente no es lo que necesitamos en este caso.

Aritmética modular :en matemáticas,la aritmética modulares un sistema de aritmética para números enteros, donde los números se «envuelven» cuando alcanzan un cierto valor, llamado módulo.

Congruencia: dado cualquier número entero N , llamado módulo, se dice que dos números enteros a y b son congruentes módulo N si producen el mismo resto cuando se dividen por N , es decir,

a = pN + r y b = qN + r , donde 0 ≤ r < |N| es el resto común.

El módulo de congruencia N se denota como a ≡ b (mod N) 
donde los paréntesis significan que (mod N) se aplica a toda la ecuación, no solo al lado derecho (aquí b ).

Ejemplos:

  • -5 ≡ 2 (módulo 7)
  • -14 ≡ 19 (módulo 11)

Analizando el primer ejemplo. -5 = 7 × -1 + 2 y 2 = 7 × 0 + 2 . Tanto -5 como 2 dejan el mismo resto 2 cuando se dividen por 7 . Por lo tanto, son congruentes entre sí. 
Del mismo modo, -14 = 11 × -2 + 8 y 19 = 11 × 1 + 8 . Tanto -14 como 19 dejan el mismo resto 8 cuando se dividen por 11 . Por lo tanto, son congruentes entre sí. 

Clases de congruencia : supongamos que un mod N deja un resto r cuando se divide por N que satisface la condición 0 ≤ r < |N| . El conjunto de todos los enteros congruentes con un módulo N se denomina clase de congruencia delentero un módulo N. Por ejemplo:

  • La clase de congruencia de 3 mod 2 es {…, -5, -3, -1, 1, 3, 5, 7, … }.
  • La clase de congruencia de 7 mod 4 es {…, -9, -5, -1, 3, 7, 11, … }.

Seleccione cualquier entero de la clase de congruencia del entero a mod N como representante de esa clase. En matemáticas, se elige como representante el residuo menos positivo, el entero no negativo más pequeño que pertenece a esa clase. Por ejemplo: 

  • El representante de congruencia clase 3 mod 2 es 1.
  • El representante de la clase de congruencia 7 mod 4 es 3.

Se elige el residuo menos positivo porque es el residuo producido después de la división euclidiana .

El representante es elegido por Lenguajes de programación:

  • Si tanto a como N son positivos, en todos los lenguajes de programación, un mod N es el resto de la división euclidiana. Sin embargo, la diferencia en el resultado se observa cuando a o N son negativos o ambos son negativos. La respuesta de un mod N depende entonces de la implementación de un mod N utilizado por el lenguaje de programación. El resto producido por todos los lenguajes de programación sigue un cierto criterio, es decir, |r| < |N| .
  • Sin embargo, esto todavía deja una ambigüedad de signo si el resto es distinto de cero, entonces ocurren dos opciones posibles para el resto, una negativa (el mayor elemento negativo de la clase de congruencia de un mod N ) y la otra positiva (el elemento menos positivo). de la clase de congruencia de un mod N ). Otros elementos no cumplen los criterios de |r| < |N| .
  • Es por eso que hay diferentes resultados cuando -3 mod 2 se realiza en C y Python . Ambos están produciendo los resultados correctos. Simplemente no están generando el representante elegido matemáticamente de un mod N .
  • En C , -3 mod 2 devuelve -1 , que es una clase miembro de -3 mod 2 . Sin embargo, Python devuelve 1 , que nuevamente es una clase miembro de -3 mod 2 . Además, tanto la respuesta volvió a satisfacer la condición dada de |r| < |N| .

Implementaciones de % en lenguajes de programación : muchos lenguajes de programación como C , C++ , Java , JavaScript usan una implementación similar a la que se proporciona a continuación. El resto se devuelve según la ecuación

r = a – N*trunc(a/N)

A continuación se muestra la implementación de la explicación anterior:

C++14

// C++14 program to illustrate modulo
// operations using the above equation
#include <bits/stdc++.h>
using namespace std;
 
// Function to calculate and
// return the remainder of a % n
int truncMod(int a, int n)
{
     
    // (a / n) implicitly gives
    // the truncated result
    int q = a / n;
 
    return a - n * q;
}
 
// Driver Code
int main()
{
    int a, b;
 
    // Modulo of two positive numbers
    a = 9;
    b = 4;
    cout << a << " % "
         << b << " = "
         << truncMod(a, b) << endl;
 
    // Modulo of a negative number
    // by a positive number
    a = -9;
    b = 4;
    cout << a << " % "
         << b << " = "
         << truncMod(a, b) << endl;
 
    // Modulo of a positive number
    // by a negative number
    a = 9;
    b = -4;
    cout << a << " % "
         << b << " = "
         << truncMod(a, b) << endl;
 
    // Modulo of two negative numbers
    a = -9;
    b = -4;
    cout << a << " % "
         << b << " = "
         << truncMod(a, b) << endl;
}
 
// This code is contributed by mohit kumar 29

Java

// Java program to illustrate modulo
// operations using the above equation
class GFG {
 
    // Function to calculate and
    // return the remainder of a % n
    static int truncMod(int a, int n)
    {
        // (a / n) implicitly gives
        // the truncated result
        int q = a / n;
 
        return a - n * q;
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        int a, b;
 
        // Modulo of two positive numbers
        a = 9;
        b = 4;
        System.out.println(a + " % " + b + " = "
                           + truncMod(a, b));
 
        // Modulo of a negative number
        // by a positive number
        a = -9;
        b = 4;
        System.out.println(a + " % " + b + " = "
                           + truncMod(a, b));
 
        // Modulo of a positive number
        // by a negative number
        a = 9;
        b = -4;
        System.out.println(a + " % " + b + " = "
                           + truncMod(a, b));
 
        // Modulo of two negative numbers
        a = -9;
        b = -4;
        System.out.println(a + " % " + b + " = "
                           + truncMod(a, b));
    }
}

Python3

# Python3 program to illustrate modulo
# operations using the above equation
 
# Function to calculate and
# return the remainder of a % n
def truncMod(a, n):
   
    # (a / n) implicitly gives
    # the truncated result
    q = a // n
    return a - n * q
 
# Driver Code
if __name__ == '__main__':
   
    # Modulo of two positive numbers
    a = 9
    b = 4
    print(a,"%",b,"=",truncMod(a, b))
 
    # Modulo of a negative number
    # by a positive number
    a = -9
    b = 4
    print(a,"%",b,"=",truncMod(a, b))
 
    # Modulo of a positive number
    # by a negative number
    a = 9
    b = -4
    print(a,"%",b,"=",truncMod(a, b))
 
    # Modulo of two negative numbers
    a = -9
    b = -4
    print(a,"%",b,"=",truncMod(a, b))
     
    # This code is contributed by SURENDRA_GANGWAR.

C#

// C# program for the above approach
using System;
public class GFG
{
 
  // Function to calculate and
  // return the remainder of a % n
  static int truncMod(int a, int n)
  {
     
    // (a / n) implicitly gives
    // the truncated result
    int q = a / n;
    return a - n * q;
  }
 
  // Driver Code
  static public void Main()
  {
 
    int a, b;
 
    // Modulo of two positive numbers
    a = 9;
    b = 4;
    Console.WriteLine(a + " % " + b + " = "
                      + truncMod(a, b));
 
    // Modulo of a negative number
    // by a positive number
    a = -9;
    b = 4;
    Console.WriteLine(a + " % " + b + " = "
                      + truncMod(a, b));
 
    // Modulo of a positive number
    // by a negative number
    a = 9;
    b = -4;
    Console.WriteLine(a + " % " + b + " = "
                      + truncMod(a, b));
 
    // Modulo of two negative numbers
    a = -9;
    b = -4;
    Console.WriteLine(a + " % " + b + " = "
                      + truncMod(a, b));
  }
}
 
// This code is contributed by snjoy_62.

Javascript

<script>
 
// JavaScript program to illustrate modulo
// operations using the above equation
 
// Function to calculate and
    // return the remainder of a % n
function truncMod(a,n)
{
    // (a / n) implicitly gives
        // the truncated result
        let q = Math.round(a / n);
         
        return a - (n * q);
}
 
let a, b;
// Modulo of two positive numbers
a = 9;
b = 4;
document.write(a + " % " + b + " = "
                   + truncMod(a, b)+"<br>");
 
// Modulo of a negative number
// by a positive number
a = -9;
b = 4;
document.write(a + " % " + b + " = "
                   + truncMod(a, b)+"<br>");
 
// Modulo of a positive number
// by a negative number
a = 9;
b = -4;
document.write(a + " % " + b + " = "
                   + truncMod(a, b)+"<br>");
 
// Modulo of two negative numbers
a = -9;
b = -4;
document.write(a + " % " + b + " = "
                   + truncMod(a, b)+"<br>");
 
 
// This code is contributed by patel2127
 
</script>
Producción: 

9 % 4 = 1
-9 % 4 = -1
9 % -4 = 1
-9 % -4 = -1

 

Nota: Otros lenguajes de programación con la implementación anterior generan resultados similares. Note algo interesante, cuando el dividendo es negativo, la respuesta producida también será negativa, y será el mayor miembro negativo de esa clase de congruencia . Cuando el dividendo es positivo, la respuesta producida también será positiva y el miembro menos positivo de esa clase de congruencia .

Muchos lenguajes de programación como Python , Ruby y Perl usan una implementación similar a la que se proporciona a continuación. El resto se devuelve según la ecuación

r = a – N × suelo(a/b)

A continuación se muestra la implementación de la explicación anterior:

C++

// C++ program to illustrate modulo
// operations using the above equation
#include <bits/stdc++.h>
using namespace std;
 
// Function to calculate and
// return the remainder of a % n
int floorMod(int a, int n)
{
     
    // Type casting is necessary
    // as (int) / (int) will give
    // int result, i.e. -3 / 2
    // will give -1 and not -1.5
    int q = (int)floor((double)a / n);
 
    // Return the resultant remainder
    return a - n * q;
}
 
// Driver Code
int main()
{
    int a, b;
 
    // Modulo of two positive numbers
    a = 9;
    b = 4;
    cout << a << " % " << b
         << " = " << floorMod(a, b) << "\n";
 
    // Modulo of a negative number
    // by a positive number
    a = -9;
    b = 4;
    cout << a << " % " << b
         << " = " << floorMod(a, b) << "\n";
 
    // Modulo of a positive number
    // by a negative number
    a = 9;
    b = -4;
    cout << a << " % " << b
         << " = " << floorMod(a, b) << "\n";
 
    // Modulo of two negative numbers
    a = -9;
    b = -4;
    cout << a << " % " << b
         << " = " << floorMod(a, b) << "\n";
 
    return 0;
}
 
// This code is contributed by Kingash

Java

// Java program to illustrate modulo
// operations using the above equation
public class GFG {
 
    // Function to calculate and
    // return the remainder of a % n
    static int floorMod(int a, int n)
    {
        // Type casting is necessary
        // as (int) / (int) will give
        // int result, i.e. -3 / 2
        // will give -1 and not -1.5
        int q = (int)Math.floor((double)a / n);
 
        // Return the resultant remainder
        return a - n * q;
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        int a, b;
 
        // Modulo of two positive numbers
        a = 9;
        b = 4;
        System.out.println(a + " % " + b + " = "
                           + floorMod(a, b));
 
        // Modulo of a negative number
        // by a positive number
        a = -9;
        b = 4;
        System.out.println(a + " % " + b + " = "
                           + floorMod(a, b));
 
        // Modulo of a positive number
        // by a negative number
        a = 9;
        b = -4;
        System.out.println(a + " % " + b + " = "
                           + floorMod(a, b));
 
        // Modulo of two negative numbers
        a = -9;
        b = -4;
        System.out.println(a + " % " + b + " = "
                           + floorMod(a, b));
    }
}

C#

// C# program to illustrate modulo
// operations using the above equation
using System;
 
class GFG{
     
// Function to calculate and
// return the remainder of a % n
static int floorMod(int a, int n)
{
     
    // Type casting is necessary
    // as (int) / (int) will give
    // int result, i.e. -3 / 2
    // will give -1 and not -1.5
    int q = (int)Math.Floor((double)a / n);
 
    // Return the resultant remainder
    return a - n * q;
}
 
// Driver code
static public void Main()
{
    int a, b;
 
    // Modulo of two positive numbers
    a = 9;
    b = 4;
   Console.WriteLine(a + " % " + b + " = " +
                     floorMod(a, b));
 
    // Modulo of a negative number
    // by a positive number
    a = -9;
    b = 4;
    Console.WriteLine(a + " % " + b + " = " +
                      floorMod(a, b));
 
    // Modulo of a positive number
    // by a negative number
    a = 9;
    b = -4;
    Console.WriteLine(a + " % " + b + " = " +
                      floorMod(a, b));
 
    // Modulo of two negative numbers
    a = -9;
    b = -4;
    Console.WriteLine(a + " % " + b + " = " +
                      floorMod(a, b));
}
}
 
// This code is contributed by offbeat

Javascript

<script>
 
// JavaScript program to illustrate modulo
// operations using the above equation
 
 // Function to calculate and
    // return the remainder of a % n
function floorMod(a,n)
{
    // Type casting is necessary
        // as (int) / (int) will give
        // int result, i.e. -3 / 2
        // will give -1 and not -1.5
        let q = Math.floor(Math.floor(a / n));
  
        // Return the resultant remainder
        return a - n * q;
}
 
// Driver Code
let a, b;
  
// Modulo of two positive numbers
a = 9;
b = 4;
document.write(a + " % " + b + " = "
                   + floorMod(a, b)+"<br>");
 
// Modulo of a negative number
// by a positive number
a = -9;
b = 4;
document.write(a + " % " + b + " = "
                   + floorMod(a, b)+"<br>");
 
// Modulo of a positive number
// by a negative number
a = 9;
b = -4;
document.write(a + " % " + b + " = "
                   + floorMod(a, b)+"<br>");
 
// Modulo of two negative numbers
a = -9;
b = -4;
document.write(a + " % " + b + " = "
                   + floorMod(a, b)+"<br>");
 
 
// This code is contributed by unknown2108
 
</script>
Producción: 

9 % 4 = 1
-9 % 4 = 3
9 % -4 = -3
-9 % -4 = -1

 

Nota: Otros lenguajes de programación que tienen la implementación anterior generan un resultado similar. Ahora bien, cuando el divisor es negativo, la respuesta producida también será negativa, así como el mayor miembro negativo de esa clase de congruencia . Cuando el divisor es positivo , la respuesta producida también será positiva, y será el miembro menos positivo de esa clase de congruencia .

Todos los idiomas están produciendo resultados correctos. Simplemente están eligiendo diferentes representantes de esa clase de solución congruente. Para producir solo el residuo menos positivo de la clase congruente como respuesta, independientemente de la implementación utilizada.

A continuación se muestra la implementación del enfoque anterior:

C++

// C++ program for the above idea
#include <bits/stdc++.h>
using namespace std;
 
// Driver Code
int main()
{
    int a, b, r;
 
    // Modulo of two positive numbers
    a = 9;
    b = 4;
    r = a % b > 0 ? a % b : abs(b) + a % b;
    cout << a << " % " << b << " = " << r << "\n";
 
    // Modulo of a negative number
    // by a positive number
    a = -9;
    b = 4;
    r = a % b > 0 ? a % b : abs(b) + a % b;
    cout << a << " % " << b << " = " << r << "\n";
 
    // Modulo of a positive number
    // by a negative number
    a = 9;
    b = -4;
    r = a % b > 0 ? a % b : abs(b) + a % b;
    cout << a << " % " << b << " = " << r << "\n";
 
    // Modulo of two negative numbers
    a = -9;
    b = -4;
    r = a % b > 0 ? a % b : abs(b) + a % b;
    cout << a << " % " << b << " = " << r << "\n";
 
    return 0;
}
 
// This code is contributed by Kingash

Java

// Java program for the above idea
public class PositiveModulus {
    // Driver Code
    public static void main(String args[])
    {
        int a, b, r;
 
        // Modulo of two positive numbers
        a = 9;
        b = 4;
        r = a % b > 0 ? a % b : Math.abs(b) + a % b;
        System.out.println(a + " % " + b + " = " + r);
 
        // Modulo of a negative number
        // by a positive number
        a = -9;
        b = 4;
        r = a % b > 0 ? a % b : Math.abs(b) + a % b;
        System.out.println(a + " % "
                           + b + " = " + r);
 
        // Modulo of a positive number
        // by a negative number
        a = 9;
        b = -4;
        r = a % b > 0 ? a % b : Math.abs(b) + a % b;
        System.out.println(a + " % "
                           + b + " = " + r);
 
        // Modulo of two negative numbers
        a = -9;
        b = -4;
        r = a % b > 0 ? a % b : Math.abs(b) + a % b;
        System.out.println(a + " % "
                           + b + " = " + r);
    }
}

C#

// C# program for the above idea
using System;
using System.Collections.Generic;
 
class GFG{
 
// Driver Code
public static void Main(string[] args)
{
    int a, b, r;
 
    // Modulo of two positive numbers
    a = 9;
    b = 4;
    r = a % b > 0 ? a % b : Math.Abs(b) + a % b;
    Console.WriteLine(a + " % " + b + " = " + r);
 
    // Modulo of a negative number
    // by a positive number
    a = -9;
    b = 4;
    r = a % b > 0 ? a % b : Math.Abs(b) + a % b;
    Console.WriteLine(a + " % " + b + " = " + r);
 
    // Modulo of a positive number
    // by a negative number
    a = 9;
    b = -4;
    r = a % b > 0 ? a % b : Math.Abs(b) + a % b;
    Console.WriteLine(a + " % " + b + " = " + r);
 
    // Modulo of two negative numbers
    a = -9;
    b = -4;
    r = a % b > 0 ? a % b : Math.Abs(b) + a % b;
    Console.WriteLine(a + " % " + b + " = " + r);
}
}
 
// This code is contributed by avijitmondal1998

Javascript

<script>
 
let a, b, r;
  
// Modulo of two positive numbers
a = 9;
b = 4;
r = a % b > 0 ? a % b : Math.abs(b) + a % b;
document.write(a + " % " + b + " = " + r+"<br>");
 
// Modulo of a negative number
// by a positive number
a = -9;
b = 4;
r = a % b > 0 ? a % b : Math.abs(b) + a % b;
document.write(a + " % "
                   + b + " = " + r+"<br>");
 
// Modulo of a positive number
// by a negative number
a = 9;
b = -4;
r = a % b > 0 ? a % b : Math.abs(b) + a % b;
document.write(a + " % "
                   + b + " = " + r+"<br>");
 
// Modulo of two negative numbers
a = -9;
b = -4;
r = a % b > 0 ? a % b : Math.abs(b) + a % b;
document.write(a + " % "
                   + b + " = " + r+"<br>");
 
 
 
 
// This code is contributed by unknown2108
</script>
Producción: 

9 % 4 = 1
-9 % 4 = 3
9 % -4 = 1
-9 % -4 = 3

 

Publicación traducida automáticamente

Artículo escrito por anujanonymous y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *