Dies mag zu einfach sein, aber es ist eine echte Frage ...
2
Ein verwandter Beitrag und ein Blog, in dem gelesen werden muss, warum der %Operator nicht der Moduloperator in C # ist.
RBT
Antworten:
123
Bevor Sie Fragen dieser Art stellen, lesen Sie bitte die MSDN-Dokumentation .
Wenn Sie zwei Ganzzahlen teilen, ist das Ergebnis immer eine Ganzzahl. Das Ergebnis von 7/3 ist beispielsweise 2. Um den Rest von 7/3 zu bestimmen, verwenden Sie den Restoperator ( % ).
int a =5;int b =3;int div = a / b;//quotient is 1int mod = a % b;//remainder is 2
% gibt den Rest zurück, nicht den Modul (wie Sie hervorheben). Sie sind nicht dasselbe und können Probleme verursachen, wenn ungewöhnliche Fälle behandelt werden (z. B. negative Indizes). Es kann jedoch wie der Moduloperator verwendet werden, wenn nur nach jeder 10. Iteration eines schwach positiven Indexers gesucht wird. Vielleicht könnten Sie erklären, wie man den realen Modul berechnet?
Cor_Blimey
1
Es stimmt, ich habe solche Beiträge gelesen und hatte Probleme in meiner Bewerbung :)
Apokalypse
1
... Was genau ist der Sinn der Erklärung aund bwenn Sie sie nicht verwenden werden? : D
Leviathanbadger
@ Aboveyou00: das für dich behoben!
Sir Crispalot
1
Die Antwort ist nicht so einfach wie diese Antwort behauptet, wie andere ebenfalls betont haben, und kann zu schwer zu debuggenden Fehlern führen. Siehe /programming/10065080/mod-explanation
Dies sollte meiner Meinung nach die richtige Antwort sein, da es den Quotienten UND den Rest in einer Funktion liefert. Ich bin mir nicht sicher, welcher Ansatz besser funktioniert (mit "a / b", um den Quotienten zu erhalten, und dann mit "a% b", um den Rest oder Math.DivRem zu erhalten), aber dieser Ansatz ist sicherlich viel besser zu lesen (in meinem Fall brauche ich Quotient und Rest kennen) - danke!
Igor
2
@Igor danke, als die ursprüngliche Frage beantwortet wurde, existierte diese Funktion nicht! Die Existenz der Funktion lässt jedoch die Bemerkung von as-cii über das Überprüfen der Dokumentation etwas albern aussehen .... :)
danodonovan
5
Nur um Verwirrung zu vermeiden, werden Math.DivRemdiv und mod nicht in einer Operation berechnet. Es ist nur eine Hilfsfunktion und der Quellcode lautet genau : public static int DivRem(int a, int b, out int result) { result = a%b; return a/b; }.
NightElfik
9
@ NightElfik Die Implementierung könnte sich in Zukunft ändern, und es ist für die Laufzeit einfacher, einen Methodenaufruf für die Optimierung zu identifizieren als disjunkte divund remAnweisungen
kbolino
5
@kbolino Das ist eine große Vorhersage, da sie hat geändert , zumindest in .NET - Core, zu teilen und subtrahieren. In RyuJIT sind weitere Optimierungen geplant, um einen einzelnen x86-Div-Befehl zu verwenden. Zugegebenermaßen sollten die JIT-Änderungen auch die Operatoren %und erkennen /, wenn sie einzeln verwendet werden.
Sie können also Ihre eigenen würfeln, obwohl dies weitaus langsamer ist als der eingebaute% -Operator:
publicstaticintMod(int a,int n){return a -(int)((double)a / n)* n;}
Edit: wow, hier ursprünglich ziemlich schlecht geschrieben, danke @joren, dass du mich erwischt hast
Jetzt verlasse ich mich hier auf die Tatsache, dass Division + Cast-to-Int in C # äquivalent ist Math.Floor(dh den Bruchteil fallen lässt), aber eine "wahre" Implementierung wäre stattdessen so etwas wie:
publicstaticintMod(int a,int n){return a -(int)Math.Floor((double)a / n)* n;}
Tatsächlich können Sie die Unterschiede zwischen% und "wahrem Modul" wie folgt erkennen:
var modTest =from a inEnumerable.Range(-3,6)from b inEnumerable.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);}
Ergebnisse:
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|False0|-3|0|0|True0|-2|0|0|True0|-1|0|0|True0|1|0|0|True0|2|0|0|True1|-3|1|-2|False1|-2|1|-1|False1|-1|0|0|True1|1|0|0|True1|2|1|1|True2|-3|2|-1|False2|-2|0|0|True2|-1|0|0|True2|1|0|0|True2|2|0|0|True
"Jetzt verlasse ich mich hier auf die Tatsache, dass die Ganzzahldivision in C # Math.Floor entspricht (dh den Bruchteil fallen lässt)" - aber das ist es nicht. Integer Divison rundet gegen Null, Math.Floor rundet gegen negative Unendlichkeit.
Joren
@ Joren Sorry, aber nein - versuchen Sie dies: Enumerable.Range(0, 10).Select(x => (double)x / 10.0).Select(x => (int)x).ToList().ForEach(x => Console.WriteLine(x));- alle
Nullen
2
Zunächst spreche ich über die Ganzzahldivision . Was passiert, wenn Sie eine Gleitkommadivision durchführen und dann in eine Ganzzahl umwandeln, ist irrelevant (obwohl dies das gleiche Ergebnis liefert). Zweitens bin ich mir nicht sicher, warum Sie erwarten würden, dass ganze Zahlen zwischen 0 und 9 etwas anderes als 0 ergeben, nachdem Sie durch 10 geteilt und auf den ganzzahligen Teil abgeschnitten haben. Wenn dies zu 1 führen würde, würde dies von Null weg oder in Richtung positive Unendlichkeit runden . Drittens gibt es keinerlei Unterschied zwischen einer Rundung gegen Null und einer Rundung gegen negative Unendlichkeit für positive Zahlen, sodass Sie das Problem nicht einmal ansprechen.
Joren
Math.Floor(-10.0 / 3.0)und -10 / 3sind nicht dasselbe.
Joren
@joren ah, ich sehe die Trennung hier - nein, ich führe keine Ganzzahldivision durch , ich führe eine Doppeldivision durch und wandle dann das Ergebnis in eine Ganzzahl um - ganz anders.
JerKimball
-4
Lesen Sie zwei Ganzzahlen vom Benutzer. Berechnen / zeigen Sie dann den Rest und den Quotienten an.
// When the larger integer is divided by the smaller integerConsole.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();
%
Operator nicht der Moduloperator in C # ist.Antworten:
Bevor Sie Fragen dieser Art stellen, lesen Sie bitte die MSDN-Dokumentation .
quelle
a
undb
wenn Sie sie nicht verwenden werden? : DEs gibt auch
Math.DivRem
quelle
Math.DivRem
div und mod nicht in einer Operation berechnet. Es ist nur eine Hilfsfunktion und der Quellcode lautet genau :public static int DivRem(int a, int b, out int result) { result = a%b; return a/b; }
.div
undrem
Anweisungen%
und erkennen/
, wenn sie einzeln verwendet werden.Die Division erfolgt mit dem
/
Operator:Die Modulo-Division erfolgt mit dem
%
Operator:quelle
Lustige Tatsache!
Die 'Modul'-Operation ist definiert als:
Ref: Modulare Arithmetik
Sie können also Ihre eigenen würfeln, obwohl dies weitaus langsamer ist als der eingebaute% -Operator:
Edit: wow, hier ursprünglich ziemlich schlecht geschrieben, danke @joren, dass du mich erwischt hast
Jetzt verlasse ich mich hier auf die Tatsache, dass Division + Cast-to-Int in C # äquivalent ist
Math.Floor
(dh den Bruchteil fallen lässt), aber eine "wahre" Implementierung wäre stattdessen so etwas wie:Tatsächlich können Sie die Unterschiede zwischen% und "wahrem Modul" wie folgt erkennen:
Ergebnisse:
quelle
Enumerable.Range(0, 10).Select(x => (double)x / 10.0).Select(x => (int)x).ToList().ForEach(x => Console.WriteLine(x));
- alleMath.Floor(-10.0 / 3.0)
und-10 / 3
sind nicht dasselbe.Lesen Sie zwei Ganzzahlen vom Benutzer. Berechnen / zeigen Sie dann den Rest und den Quotienten an.
quelle