wake-up-neo.com

Wie macht Java Modulusberechnungen mit negativen Zahlen?

Mache ich Modul falsch? Denn in Java soll -13 % 64-13 auswerten, aber ich bekomme 51.

86
Jakir00

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;
}
98
Mark Byers

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

69
Caner

Sind Sie sicher, dass Sie in Java arbeiten? weil Java wie erwartet -13% 64 = -13 ergibt. Das Zeichen der Dividende!

19
Keyxeq

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.

14
starblue

sie können verwenden 

(x % n) - (x < 0 ? n : 0);
5
ruslik

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?

3
Nava Carmon

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.

2
wallyk

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/Xr den Rest.
Z % X gibt den Rest von Z/X zurück. 

1
user415789

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.

1
Andreas

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

1
Salman Paracha

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.

0
kudesiaji

In den neuesten Java-Versionen erhalten Sie -13%64 = -13. Die Antwort wird immer ein Zählerzeichen haben.

0

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

0
Robert Green