Frage

Können Sie mir bitte sagen, wie viel es kostet? (-2) % 5?Laut meinem Python-Interpreter ist es 3, aber haben Sie eine kluge Erklärung dafür?

Ich habe gelesen, dass das Ergebnis in einigen Sprachen maschinenabhängig sein kann, bin mir aber nicht sicher.

War es hilfreich?

Lösung

Übrigens:Die meisten Programmiersprachen würden mit Python nicht einverstanden sein und das Ergebnis liefern -2.Abhängig von der Interpretation des Moduls ist dies richtig.Die am meisten anerkannte mathematische Definition besagt jedoch, dass der Modul von A Und B ist der (streng positive) Rest R der Teilung von A / B.Genauer gesagt: 0 <= R < B per Definition.

Andere Tipps

Das Ergebnis der Modulus-Operation auf Negative scheint von der Programmiersprache abhängig zu sein und hier ist eine Auflistung http://en.wikipedia.org/wiki/Modulo_operation

Ihr Python-Interpreter ist korrekt.Eine (dumme) Möglichkeit, einen Modul zu berechnen, besteht darin, den Modul zu subtrahieren oder zu addieren, bis der resultierende Wert zwischen 0 und (Modul − 1) liegt.

z.B.:13 mod 5 = (13 − 5) mod 5 = (13 − 10) mod 5 = 3

oder in deinem Fall:−2 mod 5 = (−2 + 5) mod 5 = 3

Wie es in der Dokumentation heißt Binäre Rechenoperationen, Python stellt sicher, dass:

Die ganzzahligen Divisions- und Modulo-Operatoren sind durch die folgende Identität verbunden: x == (x/y)*y + (x%y).Ganzzahldivision und Modulo sind auch mit der eingebauten Funktion divmod() verbunden: divmod(x, y) == (x/y, x%y).

Und wirklich,

>>> divmod(-2, 5)
(-1, 3).

Eine andere Möglichkeit, die Einheitlichkeit dieser Methode zu veranschaulichen, ist die Berechnung divmod für eine kleine Zahlenfolge:

>>> for number in xrange(-10, 10):
...     print divmod(number, 5)
...
(-2, 0)
(-2, 1)
(-2, 2)
(-2, 3)
(-2, 4)
(-1, 0)
(-1, 1)
(-1, 2)
(-1, 3)
(-1, 4)
(0, 0)
(0, 1)
(0, 2)
(0, 3)
(0, 4)
(1, 0)
(1, 1)
(1, 2)
(1, 3)
(1, 4)

Na ja, 0 % 5 müsste 0 sein, oder?

-1 % 5 sollte 4 sein, da dies die nächste zulässige Ziffer in umgekehrter Richtung ist (d. h. es kann nicht 5 sein, da diese außerhalb des Bereichs liegt).

Und dieser Logik folgend muss -2 gleich 3 sein.

Der einfachste Weg, sich vorzustellen, wie es funktionieren wird, besteht darin, so lange 5 zu addieren oder zu subtrahieren, bis die Zahl zwischen 0 (einschließlich) und 5 (ausschließlich) liegt.

Ich bin mir bei der Maschinenabhängigkeit nicht sicher – ich habe noch nie eine solche Implementierung gesehen, aber ich kann nicht sagen, dass sie nie durchgeführt wurde.

Wie in anderen Antworten erläutert, gibt es viele Möglichkeiten für eine Modulo-Operation mit negativen Werten.Im Allgemeinen führen unterschiedliche Sprachen (und unterschiedliche Maschinenarchitekturen) zu unterschiedlichen Ergebnissen.

Entsprechend der Python-Referenzhandbuch,

Der Modulo-Operator liefert immer ein Ergebnis mit demselben Vorzeichen wie sein zweiter Operand (oder Null);Der Absolutwert des Ergebnisses ist grundsätzlich kleiner als der Absolutwert des zweiten Operanden.

ist die Wahl, die Python trifft.Grundsätzlich ist Modulo so definiert, dass immer gilt:

x == (x/y)*y + (x%y)

es macht also Sinn, dass (-2)%5 = -2 - (-2/5)*5 = 3

Nun, -2 dividiert durch 5 wäre 0 mit einem Rest von 3.Ich glaube nicht, dass das stark von der Plattform abhängig sein sollte, aber ich habe schon seltsamere Dinge gesehen.

Es ist tatsächlich 3.In Modulararithmetik, ein Modul ist einfach der Rest einer Division, und der Rest von -2 dividiert durch 5 ist 3.

Das Ergebnis hängt von der Sprache ab.Python gibt das Vorzeichen des Divisors zurück, während c# beispielsweise das Vorzeichen des Dividenden zurückgibt (d. h.-2 % 5 gibt -2 in c# zurück).

Eine Erklärung könnte sein, dass negative Zahlen mit gespeichert werden 2er-Komplement.Wenn der Python-Interpreter versucht, die Modulo-Operation auszuführen, konvertiert er in einen vorzeichenlosen Wert.Anstatt also (-2) % 5 auszuführen, wird tatsächlich 0xFFFF_FFFF_FFFF_FFFD % 5 berechnet, was 3 ist.

Achten Sie darauf, sich nicht auf diesem Mod-Verhalten in C/C++ auf allen Betriebssystemen und Architekturen zu verlassen.Wenn ich mich richtig erinnere, habe ich versucht, mich auf C/C++-Code zu verlassen

float x2 = x % n;

x2 im Bereich von 0 bis n-1 zu halten, aber beim Kompilieren auf einem Betriebssystem schlichen sich negative Zahlen ein, auf einem anderen Betriebssystem funktionierten die Dinge jedoch einwandfrei.Das machte das Debuggen zu einer unangenehmen Zeit, da es nur in der Hälfte der Fälle passierte!

Es scheint eine häufige Verwechslung zwischen den Begriffen „Modulo“ und „Rest“ zu geben.

In der Mathematik sollte ein Rest vorhanden sein stets konsistent mit dem Quotienten definiert werden, so dass if a / b == c rem d Dann (c * b) + d == a.Je nachdem, wie Sie Ihren Quotienten runden, erhalten Sie unterschiedliche Reste.

Modulo sollte jedoch immer ein Ergebnis liefern 0 <= r < divisor, was nur dann mit der Division rund auf minus unendlich konsistent ist, wenn Sie negative ganze Zahlen zulassen.Wenn bei der Division gegen Null gerundet wird (was üblich ist), sind Modulo und Rest nur für nicht negative Werte gleichwertig.

Einige Sprachen (insbesondere C und C++) definieren nicht das erforderliche Rundungs-/Restverhalten und % ist nicht eindeutig.Viele definieren Rundung als Richtung Null, verwenden jedoch den Begriff Modulo, wobei Rest korrekter wäre.Python ist insofern relativ ungewöhnlich, als es auf negative Unendlichkeit rundet, sodass Modulo und Rest gleichwertig sind.

Ada rundet in Richtung Null IIRC, hat aber beides mod Und rem Betreiber.

Die C-Richtlinie soll es Compilern ermöglichen, die effizienteste Implementierung für die Maschine auszuwählen, aber meiner Meinung nach ist dies zumindest heutzutage eine falsche Optimierung.Ein guter Compiler wird die Äquivalenz wahrscheinlich überall dort zur Optimierung verwenden können, wo eine negative Zahl nicht vorkommen kann (und mit ziemlicher Sicherheit, wenn Sie vorzeichenlose Typen verwenden).Wenn andererseits negative Zahlen auftreten können, sind Ihnen mit ziemlicher Sicherheit die Details wichtig – aus Gründen der Portabilität müssen Sie sehr sorgfältig konzipierte, überkomplexe Algorithmen und/oder Prüfungen verwenden, um sicherzustellen, dass Sie unabhängig von Rundung und Rest die gewünschten Ergebnisse erhalten Verhalten.

Mit anderen Worten: Der Gewinn für diese „Optimierung“ ist meist (wenn nicht immer) eine Illusion, wohingegen in manchen Fällen sehr reale Kosten entstehen – es handelt sich also um eine falsche Optimierung.

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