web-dev-qa-db-fra.com

% (mod) explication

Aujourd'hui, j'écrivais un programme en C #, et j'ai utilisé % pour calculer un index ... Mon programme n'a pas fonctionné, alors je l'ai débogué et j'ai réalisé que "% = "ne fonctionne pas comme dans les autres langages de programme que je connais.

Par exemple:

Dans 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 est-ce que % ne fonctionne pas comme il se doit?

33
Wolfy

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

Tu demandes:

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

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

int mod(int a, int n)
{
    int result = a % n;
    if ((result<0 && n>0) || (result>0 && n<0)) {
        result += n;
    }
    return result;
}
15
David Heffernan

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 celle-ci:

int mod(int a, int n) {
    return ((a%n)+n) % n;
}
6

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

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

Exemple : on peut dire "Il est 16h30" ou on peut dire "Il est 16h30". Les deux formes signifient exactement le même temps, mais en sont différentes représentations.

Ainsi, les deux Python et C # sont corrects! Les nombres sont les mêmes dans le modulo 5 arithmétique que vous avez choisi . Il aurait également été mathématiquement correct de retourner (5, 6, 7, 8, 9) par exemple. Juste un peu bizarre.

Quant au choix de la représentation (en d'autres termes, le choix de la façon de représenter les nombres négatifs), il s'agit simplement d'un choix de conception différent entre les deux langues.

Cependant, ce n'est pas du tout ce que fait réellement l'opérateur% en C #. L'opérateur% n'est pas l'opérateur de module canonique; c'est l'opérateur restant. L'opérateur A% B répond en fait à la question "Si je divise 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


Extrait rapide pour obtenir le module canonique:

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

Implémentation 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
Sklivvz

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

1
Hauleth