Mache ich Modul falsch? Denn in Java soll -13 % 64
-13
auswerten, aber ich bekomme 51
.
Beide Definitionen des Moduls negativer Zahlen werden verwendet - einige Sprachen verwenden eine Definition, andere die andere.
Wenn Sie für negative Eingänge eine negative Zahl erhalten möchten, können Sie Folgendes verwenden:
int r = x % n;
if (r > 0 && x < 0)
{
r -= n;
}
Ebenso, wenn Sie eine Sprache verwendet haben, die eine negative Zahl bei einer negativen Eingabe zurückgibt, und Sie die positive Sprache bevorzugen würden
int r = x % n;
if (r < 0)
{
r += n;
}
Da "mathematisch" sind beide korrekt:
-13 % 64 = -13 (on modulus 64)
-13 % 64 = 51 (on modulus 64)
Eine der Optionen musste von Java-Sprachentwicklern ausgewählt werden und sie wählten:
das Vorzeichen des Ergebnisses entspricht dem Vorzeichen der Dividende.
Sagt es in Java-Spezifikationen:
https://docs.Oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.17.3
Sind Sie sicher, dass Sie in Java arbeiten? weil Java wie erwartet -13% 64 = -13 ergibt. Das Zeichen der Dividende!
Ihr Ergebnis ist falsch für Java . Bitte geben Sie an, wie Sie dazu gekommen sind (Ihr Programm, Ihre Implementierung und Java-Version).
Aus der Java-Sprachspezifikation
15.17.3 Restoperator%
[...]
Die Restoperation für Operanden, die nach der binären numerischen Heraufstufung (§5.6.2) Ganzzahlen sind, erzeugt einen Ergebniswert, so dass (a/b) * b + (a% b) einem ..__ entspricht.
15.17.2 Abteilungsleiter /
[...]
Ganzzahlige Division rundet auf 0 .
Da/gegen Null gerundet ist (was zu Null führt), sollte das Ergebnis von% in diesem Fall negativ sein.
sie können verwenden
(x % n) - (x < 0 ? n : 0);
Ihre Antwort ist in Wikipedia: modulo operation
Darin heißt es, dass in Java der Modulo-Vorgangsvorgang derselbe ist wie der der Dividende. und da wir über den Rest der Division sprechen, ist es in Ordnung, dass in Ihrem Fall -13 zurückgegeben wird, da -13/64 = 0. -13-0 = -13.
EDIT: Sorry, deine Frage wurde falsch verstanden ... Du hast recht, Java sollte -13 geben. Können Sie mehr umgebenden Code angeben?
Die Modulo-Arithmetik mit negativen Operanden wird vom Sprachdesigner definiert, der es der Sprachimplementierung überlassen kann, der die Definition möglicherweise auf die CPU-Architektur verlagert.
Ich konnte keine Java-Sprachdefinition finden.
Thanks Ishtar, Java Language Specification für den Rest-Operator% sagt, dass das Vorzeichen des Ergebnisses mit dem Vorzeichen des Zählers übereinstimmt.
x = x + m = x - m
im Modul m
.
so -13 = -13 + 64
im Modul 64
und -13 = 51
im Modul 64
.
gehe von Z = X * d + r
aus, wenn 0 < r < X
, dann nennen wir in der Division Z/X
r
den Rest.Z % X
gibt den Rest von Z/X
zurück.
Um dies zu vermeiden, können Sie dem negativen Wert 64
(oder was auch immer Ihre Modulbasis ist) hinzufügen, bis dieser positiv ist
int k = -13;
int modbase = 64;
while (k < 0) {
k += modbase;
}
int result = k % modbase;
Das Ergebnis wird immer noch in derselben Äquivalenzklasse liegen.
Die Mod-Funktion ist definiert als der Betrag, um den eine Zahl das größte ganzzahlige Vielfache des Divisors überschreitet, der nicht größer als diese Zahl ist. Also in Ihrem Fall von
-13 % 64
das größte ganzzahlige Vielfache von 64, das -13 nicht überschreitet, ist -64. Wenn Sie nun -13 von -64 subtrahieren, entspricht dies 51 -13 - (-64) = -13 + 64 = 51
Gemäß Abschnitt 15.17.3 der JLS "erzeugt die Restoperation für Operanden, die nach binärer numerischer Vorzeichen ganze Zahlen sind, einen Ergebniswert, so dass (a/b) * b + (a% b) gleich a ..__ ist. This Identity gilt auch für den speziellen Fall, dass die Dividende die negative ganze Zahl des größtmöglichen Betrags für ihren Typ ist und der Divisor -1 ist (der Rest ist 0). "
Hoffentlich hilft das.
In den neuesten Java-Versionen erhalten Sie -13%64 = -13
. Die Antwort wird immer ein Zählerzeichen haben.
In meiner Java-Version JDK 1.8.0_05 -13% 64 = -13
sie könnten -13- (int (-13/64)) versuchen. Mit anderen Worten: Teilen Sie die Umwandlung in eine Ganzzahl ab, um den Bruchteil zu entfernen, und ziehen Sie dann den Wert vom Numerator ab So Numerator- (Int ( Zähler/Nenner)) sollte den korrekten Rest und das Vorzeichen geben