Est-ce que je fais mal le module? Parce qu'en Java -13 % 64
est censé évaluer -13
mais je reçois 51
.
%
est un opérateur de reste.
Est-ce que je fais mal le module? Parce qu'en Java -13 % 64
est censé évaluer -13
mais je reçois 51
.
%
est un opérateur de reste.
Réponses:
Les deux définitions du module des nombres négatifs sont utilisées - certains langages utilisent une définition et d'autres l'autre.
Si vous souhaitez 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 le positif:
int r = x % n;
if (r < 0)
{
r += n;
}
x % y
, A) si x
est négatif, le reste est négatif, c'est-à-dire x % y == -(-x % y)
. B) le signe de y
n'a aucun effet iex % y == x % -y
Puisque "mathématiquement" les deux sont corrects:
-13 % 64 = -13 (on modulus 64)
-13 % 64 = 51 (on modulus 64)
L'une des options a dû être choisie par les développeurs de langage Java et ils ont choisi:
le signe du résultat est égal au signe du dividende.
Le dit dans les spécifications Java:
https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.17.3
-13 % 64 = 51
alors que je m'attendais -13
?".
int result = (-5) % 3;
donne -2. int result = (-3) % 5;
donne -3. En général, int result = (-a) % b;
donne la bonne réponse lorsque | -a | > b. Afin d'obtenir le résultat correct lorsque | -a | <b nous devrions envelopper le diviseur. int result = ((-a) % b) + b;
pour négatif a ou int result = (((-a) % b) + b) % b;
pour positif ou négatif a
Votre résultat est faux pour Java. Veuillez expliquer comment vous y êtes parvenu (votre programme, implémentation et version de Java).
À partir de la spécification du langage Java
15.17.3 Opérateur de reste%
[...]
L'opération de reste pour les opérandes qui sont des entiers après promotion numérique binaire (§5.6.2) produit une valeur de résultat telle que (a / b) * b + (a% b) est égal à une.
15.17.2 Opérateur de division /
[...] La
division entière arrondit vers 0.
Puisque / est arrondi vers zéro (ce qui donne zéro), le résultat de% doit être négatif dans ce cas.
int result = (-5) % 3;
donne -2 int result = (-3) % 5;
donne -3 En général, int result = (-a) % b;
donne la bonne réponse quand | -a | > b Pour obtenir le résultat correct lorsque | -a | <b nous devrions envelopper le diviseur. int result = ((-a) % b) + b;
pour un négatif a ou int result = (((-a) % b) + b) % b;
pour un positif ou un négatif a.
(-3) % 5
le résultat correct selon la définition est -3
, et une implémentation correcte de Java devrait produire ce résultat.
(-3)%5
donne en effet -3
, et si nous voulons le reste positif, nous devons lui ajouter 5, et le résultat sera2
vous pouvez utiliser
(x % n) - (x < 0 ? n : 0);
((x % k) + k) % k
. (Bien que le vôtre soit probablement plus lisible.)
[0, sign(divisor) * divisor)
au lieu de [0, sign(dividend) * divisor)
.
Votre réponse est dans wikipedia: fonctionnement modulo
Il dit qu'en Java, le signe sur l'opération modulo est le même que celui du dividende. et puisque nous parlons du reste de l'opération de division est très bien, qu'il renvoie -13 dans votre cas, puisque -13/64 = 0. -13-0 = -13.
EDIT: Désolé, vous avez mal compris votre question ... Vous avez raison, java devrait donner -13. Pouvez-vous fournir plus de code environnant?
L'arithmétique modulo avec des opérandes négatifs est définie par le concepteur du langage, qui peut laisser le soin à l'implémentation du langage, qui peut reporter la définition à l'architecture CPU.
Je n'ai pas pu trouver de définition du langage Java.
Merci Ishtar, Spécification du langage Java pour l' opérateur de reste% dit que le signe du résultat est le même que le signe du numérateur.
Pour surmonter cela, vous pouvez ajouter 64
(ou quelle que soit 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.
x = x + m = x - m
dans le module m
.
donc -13 = -13 + 64
en module 64
et -13 = 51
en module 64
.
supposons Z = X * d + r
, si 0 < r < X
alors en division, Z/X
nous appelons r
le reste.
Z % X
renvoie le reste de Z/X
.
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
Dans ma version de Java JDK 1.8.0_05 -13% 64 = -13
vous pouvez essayer -13- (int (-13/64)) en d'autres termes, faire une division transtypée en un entier pour se débarrasser de la partie fractionnaire puis soustraire du numérateur Donc numérateur- (int (numérateur / dénominateur)) devrait donner le bon reste et signe
Dans les dernières versions de Java, vous obtenez -13%64 = -13
. La réponse aura toujours le signe du numérateur.
Selon la section 15.17.3 du JLS, "L'opération de reste pour les opérandes qui sont des nombres entiers après la promotion numérique binaire produit une valeur de résultat telle que (a / b) * b + (a% b) est égal à a. Cette identité est paire dans le cas particulier où le dividende est le nombre entier négatif de plus grande amplitude possible pour son type et le diviseur est -1 (le reste est 0). "
J'espère que cela pourra aider.
Je ne pense pas que Java renvoie 51 dans ce cas. J'exécute Java 8 sur un Mac et j'obtiens:
-13 % 64 = -13
Programme:
public class Test {
public static void main(String[] args) {
int i = -13;
int j = 64;
System.out.println(i % j);
}
}