Mod und Rest sind nicht gleich



Machen Sie sich bereit, ein äußerst pedantischer Artikel erwartet Sie, der Ihnen möglicherweise ein Interview oder ein paar Stunden erspart, während Sie einen Fehler in der Produktion entdecken!

Ich arbeite aktiv an der zweiten Staffel von The Impostor's Guide und schreibe über die RSA-Verschlüsselung für SSH, die offensichtlich der am häufigsten heruntergeladene Code in der Geschichte der IT ist.

Ich möchte diese Geschichte vollständig verstehen. Wer hat diesen Code erfunden, wie er funktioniert, warum er funktioniert und ob er in Zukunft funktioniert? Jetzt habe ich eine verdammt interessante Geschichte entdeckt . Ich bin kein Kryptomane und ich sehe andere, die buchstäblich in diesen Bereich saugen. Aber ich interessiere mich auch dafür, weil es überall kleine Nerze gibt und ich mich wie Elstern von glänzenden Dingen in tiefen Nerzen angezogen fühle . Ich bin auch sehr gut in Metaphern.

Auf jeden Fall: Letzte Woche habe ich etwas Seltsames gelernt und möchte es teilen: Es stellt sich heraus, dass Mod und der Rest der Division nicht dasselbe sind . Es ist wirklich lustig, dass einige Leser von ihren Sitzen springen und diese Worte anschreien: "Aber genau das habe ich immer versucht, dir und allen anderen zu sagen!"

Nennen Sie die Jungs aus der Sekte "Mod ist nicht der Rest"! Das ist für dich.

Was ist Mod?


Ich musste das studieren und das letzte Mal tauchte ein solches Thema auf. Dies ist eines der Dinge, die Sie kennen, sich aber nicht erinnern. Wenn Sie Mod verwenden, teilen Sie eine Zahl durch eine andere und nehmen Sie den Rest. Also: 5 mod 2 wird 1 sein, weil 5/2 = 2 mit dem Rest von 1.

Der Begriff mod bedeutet Modulo- Betrieb, in diesem Fall Modul 2. Die meisten Programmiersprachen verwenden % , um eine solche Operation zu bezeichnen: 5 % 2 = 1 .

Dort kommen wir in die seltsame Grauzone.

Die Mathematik des Zifferblatts


Ich erinnere mich, wie ich das in der Schule unterrichtet und dann vergessen habe. Es gibt eine Art von Mathematik, die als "modulare Arithmetik" bezeichnet wird und sich mit zyklischen Strukturen befasst. Der einfachste Weg, sich dies vorzustellen, ist ein Zifferblatt mit Zyklus 12. Für einen Mathematiker ist das Zifferblatt mod 12 . Wenn Sie verstehen möchten, ob es möglich ist, 253 Stunden gleichmäßig in Tage zu unterteilen, können Sie die Operation 253 mod 24 anwenden. Das Ergebnis ist 13 , die Antwort lautet also nein! Wir können nur mit Ja antworten, wenn das Ergebnis 0 ist.

Eine andere Frage, die Sie stellen können, lautet: „Wenn ich um 18 Uhr abreise, wie spät ist es bei der Ankunft in 16 Stunden?“ Dies ist 6 + 16 mod 12 , d. H. 10.

Kryptografen lieben mod , denn wenn sie mit wirklich großen Zahlen verwendet werden, können Sie so etwas wie "Einwegfunktionen" erstellen. Dies sind spezielle Funktionen, die es einfach machen, etwas in eine Richtung zu berechnen, aber nicht in die entgegengesetzte.

Wenn ich Ihnen sage, dass 9 das Ergebnis des Quadrierens ist, können Sie leicht feststellen, was die Eingabe 3 war. Bevor Sie den gesamten Prozess von Anfang bis Ende sehen. Wenn ich sage, dass 9 das Ergebnis von mod 29 , ist es schwieriger zu verstehen, was die Eingabe ist.

Kryptografen mögen diese Idee, weil sie die Restteilung mit riesigen Primzahlen verwenden können, um kryptografische Schlüssel zu generieren. Dies ist eine ganz andere Geschichte: Wenn Sie darüber lesen möchten, können Sie ein Buch kaufen oder, noch besser, meine Bemühungen unterstützen, es zu schreiben .

Wir werden jedoch nicht vom Thema abweichen.

Bleibt und Mathe des Zifferblatts


Kommen wir nun zum Punkt: Modulo und der einfache Rest sind gleich, wenn die Zahlen positiv sind, unterscheiden sich jedoch bei negativen Zahlen.

Betrachten Sie die folgende Aufgabe:

 const x = 19 % 12; console.log(x); 

Was ist der Wert von x ? Teilen Sie die Zahlen und erhalten Sie 7 als Rest von 12. Dies ist die richtige Antwort. Wie wäre es damit:

 const y = 19 % -12; console.log(y); 

Mit gewöhnlicher Mathematik können wir -12 mit -1 multiplizieren, was 12 ergibt, und wir haben noch 7 übrig, also ist unsere Antwort wieder 7.

JavaScript stimmt dem zu:



C # stimmt auch zu:



Google stimmt der ersten Aussage zu, stimmt jedoch der zweiten nicht zu:



Ruby stimmt Google zu:



Was ist hier im Namen von Dijkstra los?

Vor Stunden


Um die Frage zu beantworten, müssen Sie den Unterschied zwischen dem Rest und Modulo verstehen. Programmierer kombinieren diese Operationen , sollten dies jedoch nicht tun, da sie nur dann das gleiche Ergebnis liefern, wenn der Divisor (in unserem Fall 12) positiv ist. Sie können Fehler leicht an die Produktion senden, wenn der Divisor negativ ist.

Aber warum gibt es einen Unterschied? Betrachten Sie den positiven Teiler 19 mod 12 auf der Uhr:



Endergebnis 7. Wir wissen das und können es mathematisch beweisen. Aber was ist mit 19 mod -12 ? Hier müssen Sie andere Uhren verwenden :



Das Modul ist -12, und wir können es nicht ignorieren oder ändern, indem wir es mit -1 multiplizieren, da die modulare Arithmetik nicht so funktioniert. Die einzige Möglichkeit, das Ergebnis korrekt zu berechnen, besteht darin, die Markierungen auf der Uhr so ​​anzuordnen, dass wir uns von -12 bewegen oder die Uhr gegen den Uhrzeigersinn drehen, was das gleiche Ergebnis ergibt.

Warum nicht Tags mit -1 beginnen, zu -2 wechseln usw.? Denn in diesem Fall bewegen wir uns zurück und reduzieren das Ergebnis ständig, bis wir -12 erreichen. In diesem Moment machen wir einen Sprung von +12, und Modulo funktioniert so nicht.

Das ist eine berühmte Sache.


Bevor Sie mich für verrückt halten und ein Thema googeln: Dies ist eine bekannte Tatsache . Tatsächlich ging das MDN (Mozilla Developer Network) sogar so weit, % den Restvorgang zu nennen, nicht modulo:

Der Restoperator gibt den Rest der Division eines Operanden durch einen anderen zurück. Er akzeptiert immer das Zeichen der Dividende .

Hier ist, was Eric Lippert, einer der C # -Götter, über Modulo in C # sagt :

Dies ist jedoch überhaupt nicht das, was der% -Operator tatsächlich in C # tut. Der% -Operator ist kein kanonischer Moduloperator, sondern ein Restoperator.

Was ist mit deiner Sprache?

Na und?


Ich kann verstehen, ob Sie so weit gelesen haben und sich jetzt am Kopf kratzen und sich fragen, ob es sich lohnt, sich Sorgen zu machen. Ich denke, dass es aus zwei Gründen kostet:

  1. Ich kann mir vorstellen, wie mich diese Frage bei einem Interview überraschen wird.
  2. Ich kann mir vorstellen, wie dieser in die Produktion kommt, und die Entwickler werden mehrere Stunden lang herausfinden, warum die Mathematik nicht funktioniert.

Dies ist auch eine lustige Tatsache, falls Ihr pedantischer Programmiererfreund mitkommt.

Source: https://habr.com/ru/post/de421071/


All Articles