C'est peut-être trop basique, mais c'est une vraie question ...
2
Un connexe poste et doit lire le blog pourquoi l' %opérateur est pas l'opérateur de module en C #.
RBT
Réponses:
123
Avant de poser des questions de ce type, veuillez consulter la documentation MSDN .
Lorsque vous divisez deux entiers, le résultat est toujours un entier. Par exemple, le résultat de 7/3 est 2. Pour déterminer le reste de 7/3, utilisez l'opérateur de reste ( % ).
int a = 5;
int b = 3;
int div = a / b; //quotient is 1int mod = a % b; //remainder is 2
% renvoie le reste, pas le module (comme vous le faites remarquer). Ils ne sont pas la même chose et peuvent poser des problèmes lors du traitement de cas inhabituels (par exemple des indices négatifs). Cependant, il peut être utilisé comme l'opérateur de module lorsque l'on cherche simplement, par exemple, toutes les 10 itérations d'un indexeur faiblement positif. Peut-être pourriez-vous expliquer comment calculer le module réel?
Cor_Blimey
1
C'est vrai, j'ai lu des articles comme celui-ci, et j'ai eu des problèmes dans mon application :)
apocalypse
1
... Quel est l'intérêt de déclarer aet bsi vous n'allez pas les utiliser? : D
leviathanbadger
1
Peut-être que l'utilisateur cherchait (comme moi) une fonction DivRem, donc la question pourrait ne pas être aussi triviale qu'il n'y paraît à première vue. Merci @danodonovan
Tancredi
1
La réponse n'est pas aussi simple que cette réponse le prétend, comme d'autres l'ont également souligné, et peut conduire à des erreurs difficiles à déboguer. Voir /programming/10065080/mod-explanation
Cela devrait être la bonne réponse à mon avis, car elle fournit le quotient ET le reste dans une fonction. Je ne sais pas quelle approche fonctionne le mieux (en utilisant "a / b" pour obtenir le quotient, puis "a% b" pour obtenir le reste ou Math.DivRem), mais cette approche est certainement beaucoup plus agréable à lire (dans mon cas, j'ai besoin pour connaître le quotient et le reste) - merci!
Igor
2
@Igor merci, lorsque la question d'origine a été répondue, cette fonction n'existait pas! Cependant, l'existence de la fonction rend la remarque d'as-cii sur la vérification de la documentation un peu ridicule .... :)
danodonovan
5
Juste pour éviter toute confusion, Math.DivRemne calcule pas div et mod en une seule opération. Il est juste une fonction d'aide et son code source est exactement: public static int DivRem(int a, int b, out int result) { result = a%b; return a/b; }.
NightElfik
9
@NightElfik L'implémentation pourrait changer à l'avenir, et il est plus facile pour le runtime d'identifier un appel de méthode pour l'optimisation que disjoint divet reminstructions
kbolino
6
@kbolino C'est une excellente prédiction, car cela a changé , du moins dans .NET Core, pour diviser et soustraire. Et il y a d'autres optimisations prévues dans RyuJIT pour utiliser une seule instruction div x86, bien que les modifications JIT devraient également détecter les opérateurs %et /s'ils sont utilisés individuellement.
Vous pouvez donc lancer le vôtre, même si ce sera BEAUCOUP plus lent que l'opérateur% intégré:
publicstaticintMod(int a, int n)
{
return a - (int)((double)a / n) * n;
}
Edit: wow, mal parlé ici à l'origine, merci @joren de m'avoir attrapé
Maintenant, je m'appuie sur le fait que division + cast-to-int en C # équivaut à Math.Floor(c'est- à -dire qu'il supprime la fraction), mais une implémentation "vraie" serait plutôt quelque chose comme:
publicstaticintMod(int a, int n)
{
return a - (int)Math.Floor((double)a / n) * n;
}
En fait, vous pouvez voir les différences entre% et "vrai module" avec ce qui suit:
var modTest =
from a in Enumerable.Range(-3, 6)
from b in Enumerable.Range(-3, 6)
where b != 0let op = (a % b)
let mod = Mod(a,b)
let areSame = op == mod
selectnew
{
A = a,
B = b,
Operator = op,
Mod = mod,
Same = areSame
};
Console.WriteLine("A B A%B Mod(A,B) Equal?");
Console.WriteLine("-----------------------------------");
foreach (var result in modTest)
{
Console.WriteLine(
"{0,-3} | {1,-3} | {2,-5} | {3,-10} | {4,-6}",
result.A,
result.B,
result.Operator,
result.Mod,
result.Same);
}
"Maintenant, je me fie au fait que la division entière en C # équivaut à Math.Floor (c'est-à-dire qu'elle supprime la fraction)" - Mais ce n'est pas le cas. La division entière arrondit vers zéro, Math.Floor arrondit vers l'infini négatif.
Joren
@Joren Désolé, mais non - essayez d'exécuter ceci: Enumerable.Range(0, 10).Select(x => (double)x / 10.0).Select(x => (int)x).ToList().ForEach(x => Console.WriteLine(x));- tous les 0
JerKimball
2
Premièrement, je parle de la division entière . Que se passe-t-il si vous effectuez une division en virgule flottante puis transtypez en entier n'est pas pertinent (même si cela donne le même résultat). Deuxièmement, je ne sais pas pourquoi vous vous attendriez à ce que les entiers entre 0 et 9 donnent autre chose que 0 après avoir divisé par 10 et tronqué à la partie entière. Si cela aboutissait à 1, cela serait arrondi à partir de zéro ou vers l' infini positif . Troisièmement, il n'y a aucune différence entre arrondir vers zéro et arrondir vers l'infini négatif pour les nombres positifs, de sorte que vous ne résolvez même pas le problème.
Joren
Math.Floor(-10.0 / 3.0)et ne-10 / 3 sont pas la même chose.
Joren
@joren ah, je vois la déconnexion ici - non, je n'effectue pas de division entière , j'effectue une double division, puis je transforme le résultat en entier - très différent.
JerKimball
14
La division est effectuée à l'aide de l' /opérateur:
result = a / b;
La division Modulo se fait à l'aide de l' %opérateur:
%
opérateur est pas l'opérateur de module en C #.Réponses:
Avant de poser des questions de ce type, veuillez consulter la documentation MSDN .
int a = 5; int b = 3; int div = a / b; //quotient is 1 int mod = a % b; //remainder is 2
la source
a
etb
si vous n'allez pas les utiliser? : DIl y a aussi
Math.DivRem
quotient = Math.DivRem(dividend, divisor, out remainder);
la source
Math.DivRem
ne calcule pas div et mod en une seule opération. Il est juste une fonction d'aide et son code source est exactement:public static int DivRem(int a, int b, out int result) { result = a%b; return a/b; }
.div
etrem
instructions%
et/
s'ils sont utilisés individuellement.Fait amusant!
L'opération 'module' est définie comme:
Réf: Arithmétique modulaire
Vous pouvez donc lancer le vôtre, même si ce sera BEAUCOUP plus lent que l'opérateur% intégré:
public static int Mod(int a, int n) { return a - (int)((double)a / n) * n; }
Edit: wow, mal parlé ici à l'origine, merci @joren de m'avoir attrapé
Maintenant, je m'appuie sur le fait que division + cast-to-int en C # équivaut à
Math.Floor
(c'est- à -dire qu'il supprime la fraction), mais une implémentation "vraie" serait plutôt quelque chose comme:public static int Mod(int a, int n) { return a - (int)Math.Floor((double)a / n) * n; }
En fait, vous pouvez voir les différences entre% et "vrai module" avec ce qui suit:
var modTest = from a in Enumerable.Range(-3, 6) from b in Enumerable.Range(-3, 6) where b != 0 let op = (a % b) let mod = Mod(a,b) let areSame = op == mod select new { A = a, B = b, Operator = op, Mod = mod, Same = areSame }; Console.WriteLine("A B A%B Mod(A,B) Equal?"); Console.WriteLine("-----------------------------------"); foreach (var result in modTest) { Console.WriteLine( "{0,-3} | {1,-3} | {2,-5} | {3,-10} | {4,-6}", result.A, result.B, result.Operator, result.Mod, result.Same); }
Résultats:
A B A%B Mod(A,B) Equal? ----------------------------------- -3 | -3 | 0 | 0 | True -3 | -2 | -1 | -1 | True -3 | -1 | 0 | 0 | True -3 | 1 | 0 | 0 | True -3 | 2 | -1 | 1 | False -2 | -3 | -2 | -2 | True -2 | -2 | 0 | 0 | True -2 | -1 | 0 | 0 | True -2 | 1 | 0 | 0 | True -2 | 2 | 0 | 0 | True -1 | -3 | -1 | -1 | True -1 | -2 | -1 | -1 | True -1 | -1 | 0 | 0 | True -1 | 1 | 0 | 0 | True -1 | 2 | -1 | 1 | False 0 | -3 | 0 | 0 | True 0 | -2 | 0 | 0 | True 0 | -1 | 0 | 0 | True 0 | 1 | 0 | 0 | True 0 | 2 | 0 | 0 | True 1 | -3 | 1 | -2 | False 1 | -2 | 1 | -1 | False 1 | -1 | 0 | 0 | True 1 | 1 | 0 | 0 | True 1 | 2 | 1 | 1 | True 2 | -3 | 2 | -1 | False 2 | -2 | 0 | 0 | True 2 | -1 | 0 | 0 | True 2 | 1 | 0 | 0 | True 2 | 2 | 0 | 0 | True
la source
Enumerable.Range(0, 10).Select(x => (double)x / 10.0).Select(x => (int)x).ToList().ForEach(x => Console.WriteLine(x));
- tous les 0Math.Floor(-10.0 / 3.0)
et ne-10 / 3
sont pas la même chose.La division est effectuée à l'aide de l'
/
opérateur:La division Modulo se fait à l'aide de l'
%
opérateur:la source
Lisez deux entiers de l'utilisateur. Puis calculer / afficher le reste et le quotient,
// When the larger integer is divided by the smaller integer Console.WriteLine("Enter integer 1 please :"); double a5 = double.Parse(Console.ReadLine()); Console.WriteLine("Enter integer 2 please :"); double b5 = double.Parse(Console.ReadLine()); double div = a5 / b5; Console.WriteLine(div); double mod = a5 % b5; Console.WriteLine(mod); Console.ReadLine();
la source