Frage

Ich bin neugierig auf diese Sprachen (Java, c ...), die die mathematische Definition des Modulbetriebs ignorieren.

Was ist es, negative Werte in einer Moduloperation zurückzugeben (die per Definition immer eine positive Zahl zurückgeben sollte)?

War es hilfreich?

Lösung

Ich bezweifle, dass der Restbetreiber absichtlich für diese Semantik konzipiert wurde, was ich zustimme, nicht sehr nützlich. (Würden Sie jemals ein Kalenderprogramm schreiben, das den Wochentagen Sonntag, Anti-Saturday, Anti-Freitag, ..., Anti-Montag für Daten vor der Epoche, zeigt?)

Negative Reste sind vielmehr ein Nebeneffekt der Art und Leistungsenteilung, die definiert wird.

A rem B := A - (A div B) * B

Wenn A div B ist definiert als trunc(A/B), du bekommst c's % Operator. Wenn A div B ist definiert als floor(A/B), du bekommst Python's % Operator. Andere Definitionen sind möglich.

Die eigentliche Frage ist also:

Warum verwenden C ++, Java, C#usw. die Integer Division abschnittlich?

Denn so macht C es so.

Warum verwendet C C Abrucation Division?

Ursprünglich gab C nicht an, wie / sollte negative Zahlen bewältigen. Es überließ es der Hardware.

In der Praxis verwendete jede signifikante C -Implementierung die Abteilung für Kürzungen. 1999 wurden diese Semantik offiziell zu einem Teil des C -Standards hergestellt.

Warum verwendet Hardware eine Abteilung für Abteilung?

Weil es einfacher ist (= billiger), in Bezug auf die nicht signierte Division zu implementieren. Sie berechnen nur abs(A) div abs(B) und umdrehen das Zeichen, wenn (A < 0) xor (B < 0).

Die Bodendivision hat den zusätzlichen Schritt, 1 vom Quotienten zu subtrahieren, wenn der Rest ungleich Null ist.

Andere Tipps

Zumindest in Java ist es kein Modul -Operator - es ist ein Restbetreiber.

Ich glaube, der Grund dafür, dass es so ausgewählt wird, besteht darin, diese Beziehung (aus dem JLS) zum Laufen zu bringen:

Der Restbetrieb für Operanden, die nach der binären numerischen Werbung (§5.6.2) Ganzzahlen sind, erzeugt einen Ergebniswert, so dass (a/b)*b+(a%b) gleich a ist. Diese Identität gilt auch in dem Sonderfall, dass die Dividende die negative ganze Zahl der größtmögliche Größenordnung für seinen Typ ist und der Divisor -1 (der Rest ist 0). Aus dieser Regel folgt, dass das Ergebnis der Restoperation nur dann negativ sein kann, wenn die Dividende negativ ist und nur dann positiv sein kann, wenn die Dividende positiv ist. Darüber hinaus ist die Größe des Ergebnisses immer geringer als die Größe des Divisors.

Diese Gleichstellungsbeziehung scheint eine vernünftige Sache als Teil der Definition zu verwenden. Wenn Sie die Division in Richtung Null nehmen, um eine Selbstverständlichkeit zu sein, lässt Sie einen negativen Rest zurück.

Aus Wikipedia (meine Betonung):

Bei zwei positiven Zahlen, A (der Dividende) und N (der Divisor), kann ein Modulo (abgekürzt als Mod n) als Rest auf die Teilung von a durch n angesehen werden. Zum Beispiel würde der Ausdruck "5 mod 4" auf 1 bewertet, da 5 geteilt durch 4 einen Rest von 1 hinterlässt, während "9 Mod 3" auf 0 bewertet wird, da die Aufteilung von 9 mal 3 einen Rest von 0 verlässt; Es gibt nichts zu subtrahieren von 9 nach dem dreimaligen Multiplizieren 3. (Beachten Sie, dass die Abteilung mit einem Taschenrechner nicht das Ergebnis zeigt, auf das dieser Vorgang hier bezeichnet wird, der Quotient als Dezimalzahl ausgedrückt wird.) Wenn entweder A oder N negativ ist, bricht diese naive Definition zusammen und die Programmiersprachen unterscheiden sich in der Definition dieser Werte. Obwohl in der Regel mit A und N beide Ganzzahlen durchgeführt werden, erlauben viele Computersysteme andere Arten von numerischen Operanden. Der Zahlenbereich für ein Ganzzahlmodulo von n beträgt 0 bis n - 1. (N mod 1 ist immer 0; n mod 0 ist undefiniert, was möglicherweise zu einem "Teilungsstudium" -Fehler in Computerprogrammiersprachen) siehe modulare Arithmetik für Eine ältere und verwandte Konvention, die in der Zahlentheorie angewendet wird.

Die meisten von ihnen sind nicht definiert, um einen Modul zurückzugeben. Was sie zur Rückkehr definiert sind, ist ein Rest, für den positive und negative Werte gleichermaßen vernünftig sind.

In C oder C ++ ist es ziemlich vernünftig zu sagen, dass es alles erzeugen sollte, was die zugrunde liegende Hardware erzeugt. Diese Entschuldigung/dieser Grund funktioniert für Java jedoch nicht annähernd so gut.

Beachten Sie auch, dass der Rest in C89/90 und C ++ 98/03 entweder positiv oder negativ sein könnte, solange die Ergebnisse der Rest- und Division zusammenarbeiten (zusammenarbeiten (zusammen).(a/b)*b+a%b == a). In C99 und C ++ 11 wurden die Regeln verschärft, sodass die Teilung in Richtung Null abschneiden muss, und wenn es einen Rest gibt, muss sie negativ sein.

Ein pragmatischer Grund, einen negativen Wert für den Modul zurückzugeben, ist, dass der Hardware -Befehl, der Modul implementiert, dies tut.

Die Standards lassen diese schlecht definierte, damit Compiler alles tun können, was für sie einfacher ist.

In keinem der C- oder Java -Standards ist % als Modul -Operator bezeichnet - vielmehr gibt es die zurück Rest.

Es ist definiert, negative Zahlen für negative Dividenden zurückzugeben, damit die Beziehung (a/b)*b + a%b == a hält, so lange wie a / b ist dargestellt. Da der Divisionsbetreiber so definiert ist, dass der Rest des Restes in Richtung Null abgeschnitten wird.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top