% (mod) explication

Aujourd'Hui, j'ai écrit un programme en C#, et j'ai utilisé % pour calculer certains index... Mon programme ne fonctionne pas, donc j'ai débogué et j'ai réalisé que "%" ne fonctionne pas comme dans d'autres langues que je connais.

Par exemple:

En Python % renvoie des valeurs comme ceci:

for x in xrange (-5, 6):
     print x, "% 5 =", x % 5

-5 % 5 = 0
-4 % 5 = 1
-3 % 5 = 2
-2 % 5 = 3
-1 % 5 = 4
0 % 5 = 0
1 % 5 = 1
2 % 5 = 2
3 % 5 = 3
4 % 5 = 4
5 % 5 = 0

En C#:

for (int i = -5; i < 6; i++)
{
    Console.WriteLine(i + " % 5 = " + i % 5);
}

-5 % 5 = 0
-4 % 5 = -4
-3 % 5 = -3
-2 % 5 = -2
-1 % 5 = -1
0 % 5 = 0
1 % 5 = 1
2 % 5 = 2
3 % 5 = 3
4 % 5 = 4
5 % 5 = 0

Ai-je fait quelque chose de mal ou % ne fonctionne pas comme il se doit?

30
demandé sur Peter Mortensen 2012-04-08 22:04:28

4 réponses

Comme expliqué dans les commentaires, le comportement différent est par conception. Les différentes langues attribuent simplement des significations différentes à l'opérateur %.

Vous demandez:

Comment puis-je utiliser l'opérateur module en C#?

Vous pouvez définir vous-même un opérateur module qui se comporte de la même manière que L'opérateur Python %:

int mod(int a, int n)
{
    int result = a % n;
    if ((result<0 && n>0) || (result>0 && n<0)) {
        result += n;
    }
    return result;
}
14
répondu David Heffernan 2018-04-11 02:24:34

Les Deux réponses sont correctes. Bien que personnellement, je pense que le "toujours positif" a plus de sens.

Vous pouvez définir votre propre fonction de module qui ne donne que des réponses positives comme ceci:

int mod(int a, int n) {
    return ((a%n)+n) % n;
}
6
répondu Niet the Dark Absol 2012-04-08 19:49:36

Dans arithmétique modulaire, on définit les classes de nombres basés sur le modulo. En d'autres termes, dans modulo m arithmétique, un certain nombre n est équivalent (lire: les mêmes) n + m, n - m, n + 2m, n - 2m, etc.

On définit m "paniers" et chaque nombre tombe dans un (et un seul) d'entre eux.

Exemple : on peut dire "il est 16h30" ou un peut dire "il est 16h30". Les deux formes signifient exactement le même temps, mais sont différentes représentations de celui-ci.

Ainsi, les résultats Python et C# sont corrects! Les chiffres sont cette dans le modulo 5 l'arithmétique que vous avez choisi. Il aurait aussi été mathématiquement correct de retour (5, 6, 7, 8, 9) par exemple. Juste un peu bizarre.

Quant au choix de la représentation (en d'autres termes, le choix sur la façon de représenter les nombres négatifs), c'est-à-dire juste un cas de choix de conception différents entre les deux langues.

Cependant, ce n'est pas du tout ce que l'opérateur % fait réellement en C#. L'opérateur % n'est pas l'opérateur de module canonique; c'est l'opérateur de reste. L'opérateur A % B répond réellement à la question " si je divisais A par B en utilisant l'arithmétique entière, quel serait le reste?"

- Quelle est la différence? Reste vs Module par Eric Lippert


Rapide extrait pour obtenir le module canonique:

return ((n % m) + m) % m;

Mise en œuvre du Test:

Mono/C # :

machine:~ user$ cat mod.cs
using System;

public class Program
{
    public static void Main (string[] args)
    {
        Console.WriteLine(Mod(-2, 5));
        Console.WriteLine(Mod(-5, 5));
        Console.WriteLine(Mod(-2, -5));
    }

    public static int Mod (int n, int m)
    {
        return ((n % m) + m) % m;
    }
}

machine:~ user$ mono mod.exe
3
0
-2

Python:

machine:~ user$ cat mod.py
print -2%5;
print -5%5;
print -2%-5;

machine:~ user$ python mod.py
3
0
-2
5
répondu Sklivvz 2017-10-23 07:57:16

Consultez le tableau sur le côté droit: http://en.wikipedia.org/wiki/Modulo_operation

1
répondu Hauleth 2012-04-08 19:24:53