web-dev-qa-db-fra.com

Comment Java effectue-t-il des calculs de module avec des nombres négatifs?

Est-ce que je fais le mauvais module? Parce qu'en Java, -13 % 64 est censé être évalué à -13 mais je reçois 51.

86
Jakir00

Les deux définitions du module des nombres négatifs sont utilisées - certaines langues utilisent une définition et l’autre.

Si vous voulez obtenir un nombre négatif pour les entrées négatives, vous pouvez utiliser ceci:

int r = x % n;
if (r > 0 && x < 0)
{
    r -= n;
}

De même, si vous utilisiez une langue qui renvoie un nombre négatif sur une entrée négative et que vous préférez positif:

int r = x % n;
if (r < 0)
{
    r += n;
}
98
Mark Byers

Puisque "mathématiquement" les deux sont corrects: 

-13 % 64 = -13 (on modulus 64)  
-13 % 64 = 51 (on modulus 64)

Une des options devait être choisie par les développeurs de langage Java et ils ont choisi:

le signe du résultat est égal au signe du dividende.

Dit dans les spécifications Java:

https://docs.Oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.17.3

69
Caner

Êtes-vous sûr de travailler en Java? Parce que Java donne -13% 64 = -13 comme prévu. Le signe du dividende!

19
Keyxeq

Votre résultat est incorrect pour Java . Veuillez fournir un contexte dans lequel vous y êtes arrivé (programme, implémentation et version de Java).

A partir de Spécification du langage Java

15.17.3 Opérateur résiduel%
[...]
L’opération restante pour les opérandes qui sont des entiers après la promotion numérique binaire (§5.6.2) produit une valeur de résultat telle que (a/b) * b + (a% b) est égal à a .
15.17.2 Opérateur de division /
[...]
La division entière est arrondie à 0 .

Puisque/est arrondi à zéro (ce qui donne zéro), le résultat de% doit être négatif dans ce cas.

14
starblue

vous pouvez utiliser 

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

Votre réponse est dans wikipedia: opération modulo

On dit que, en Java, l’opération d’inscription sur modulo est la même que celle de dividende. et puisque nous parlons du reste de l’opération de division c’est très bien, elle renvoie -13 dans votre cas, puisque -13/64 = 0. -13-0 = -13. 

EDIT: Désolé, mal compris votre question ... Vous avez raison, Java devrait donner -13. Pouvez-vous fournir plus de code environnant?

3
Nava Carmon

L'arithmétique modulo avec des opérandes négatives est définie par le concepteur de langage, qui peut en laisser le soin à l'implémentation du langage, qui peut en remettre la définition à l'architecture de la CPU.

Je n'ai pas réussi à trouver une définition du langage Java.
Merci Ishtar, Spécification du langage Java pour le Opérateur du reste% indique que le signe du résultat est identique au signe du numérateur.

2
wallyk

x = x + m = x - m dans le module m.
so -13 = -13 + 64 dans le module 64 et -13 = 51 dans le module 64.
suppose Z = X * d + r, si 0 < r < X puis dans la division Z/X, nous appelons r le reste.
Z % X renvoie le reste de Z/X

1
user415789

Pour résoudre ce problème, vous pouvez ajouter 64 (ou votre base de module) à la valeur négative jusqu'à ce qu'elle soit positive

int k = -13;
int modbase = 64;

while (k < 0) {
    k += modbase;
}

int result = k % modbase;

Le résultat sera toujours dans la même classe d'équivalence.

1
Andreas

La fonction mod est définie comme la quantité par laquelle un nombre dépasse le plus grand multiple entier du diviseur qui n'est pas supérieur à ce nombre. Donc, dans votre cas de 

-13 % 64

le plus grand multiple entier de 64 qui ne dépasse pas -13 est -64. Maintenant, lorsque vous soustrayez -13 de -64, cela équivaut à 51 -13 - (-64) = -13 + 64 = 51

1
Salman Paracha

Selon la section 15.17.3 du JLS, "L’opération restante pour les opérandes qui sont des entiers après une promotion numérique binaire produit une valeur de résultat telle que (a/b) * b + (a% b) soit égal à a . L'identité est valable même dans le cas particulier où le dividende est l'entier négatif de la plus grande magnitude possible pour son type et le diviseur est -1 (le reste est égal à 0). "

J'espère que cela pourra aider.

0
kudesiaji

Dans les dernières versions de Java, vous obtenez -13%64 = -13. La réponse aura toujours un signe de numérateur.

0
vsn harish rayasam

Dans ma version de JDK Java 1.8.0_05 -13% 64 = -13

vous pouvez essayer -13- (int (-13/64)) En d’autres termes, divisez la division en un entier pour supprimer la partie fraction. numérateur/dénominateur)) doit donner le reste correct et le signe

0
Robert Green