Pourquoi l’opérateur% de Java donne-t-il des résultats différents de ceux obtenus avec ma calculasortingce pour un dividende négatif?

Comment faire pour une calculasortingce -1 mod 26 = 25, mais en C ou Java -1 % 26 == -1 . J’ai besoin d’un programme qui le résout comme la calculasortingce. Y a-t-il une différence entre les deux?

Les deux réponses (25 et -1) sont valides. C’est juste que différents systèmes ont des conventions différentes.

Celui que je vois le plus commun (en mathématiques) est:

 quotient = floor(x / y) remainder = x - quotient * y 

floor() doit arrondir vers l’infini négatif.

C’est la convention que vous donne votre calculasortingce. (Mathematica utilise également cette convention.)

Celui que je pense que la plupart des langages de programmation utilisent est:

 quotient = integerpart(x / y) remainder = x - quotient * y 

integerpart() est identique à une integerpart() float -> integer). (arrondir à zéro)

Certaines conventions préfèrent garder le rest du même signe que l’un des opérandes.

La même chose s’applique au signe du diviseur. Différentes conventions sont différentes.

“Comment venir … ?”

Il existe deux définitions communes de l’opération modulo. Java en a choisi un (“même signe de dividende”) et la calculasortingce en implémente un autre; vraisemblablement “même signe que diviseur”, bien que vous deviez faire des expériences pour en être sûr.

En fait, la page Wikipedia sur l’ opération modulo donne 4 définitions différentes de l’opérateur utilisées par différents langages de programmation. (Et certains langages de programmation vous donnent deux opérateurs avec une sémantique différente.)

Dans le cas de C, la définition dépend de la version du standard C dont vous parlez. Pour ISO C 1999, l’opérateur modulo suit la même définition que Java. Pour les versions antérieures de la norme C, la sémantique de % dépend de la mise en œuvre.

“Y a-t-il une différence entre les deux?”

Évidemment il y en a!

“J’ai besoin d’un programme qui le résout comme la calculasortingce.”

N’hésitez pas à en écrire un :-).

Mais si vous voulez juste savoir comment obtenir le module sous forme de module “même signe en tant que diviseur” en Java, voici une solution:

 int otherModulus = (a % b) + (a < 0 ? b : 0); // works for b > 0. int otherModulus = (a % b) + // works for b != 0 (b > 0 ? (a < 0 ? b : 0) : (a > 0 ? -b : 0)); 

L’arithmétique modulo avec des opérandes négatifs diffère d’une langue à l’autre et dépend de la définition de la langue à piloter. En Java, Modulus ressemble plus à Remainder .

Généralement, 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; } 

Ou, 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; } 

Par conséquent, en fonction du résultat souhaité, il est recommandé d’utiliser l’implémentation appropriée plutôt que de compter sur le langage à utiliser pour le calcul.

Notez également que le résultat attendu dans le cas de Java est décrit de manière constructive dans le JLS: section 15.17.3 - Opérateur de rest (%). Ils y motivent (a% b doit être tel que (a / b) * b + (a% b) est égal à a) mais c'est l'inclusion de cette section dans le JLS qui rend le résultat ainsi.