En Java quand tu fais
a % b
Si a est négatif, il retournera un résultat négatif au lieu de rester comme il se doit. Quelle est la meilleure façon de résoudre ce problème? La seule façon dont je peux penser est
a < 0 ? b + a : a % b
Il se comporte comme il se doit a% b = a - a/b * b; c'est-à-dire le reste.
Vous pouvez faire (a% b + b)% b
Cette expression fonctionne car le résultat de (a % b)
est nécessairement inférieur à b
, peu importe si a
est positif ou négatif. L'ajout de b
prend en charge les valeurs négatives de a
, puisque (a % b)
est une valeur négative comprise entre -b
et 0
, (a % b + b)
est nécessairement inférieur à b
et positif. Le dernier modulo existe au cas où a
était positif au départ, car si a
était positif, (a % b + b)
deviendrait plus grand que b
. Par conséquent, (a % b + b) % b
le convertit à nouveau en une taille inférieure à b
(et n'affecte pas les valeurs a
négatives).
Depuis Java 8, vous pouvez utiliser Math.floorMod (int x, int y) et Math.floorMod (long x, long y) . Ces deux méthodes donnent les mêmes résultats que la réponse de Peter.
Math.floorMod( 2, 3) = 2
Math.floorMod(-2, 3) = 1
Math.floorMod( 2, -3) = -1
Math.floorMod(-2, -3) = -2
Pour ceux qui n'utilisaient pas (ou ne pouvaient pas encore utiliser) Java 8, Guava est venu à la rescousse avec IntMath.mod () , disponible depuis Guava 11.0.
IntMath.mod( 2, 3) = 2
IntMath.mod(-2, 3) = 1
Une mise en garde: contrairement à Math.floorMod () de Java 8, le diviseur (le second paramètre) ne peut pas être négatif.
En théorie des nombres, le résultat est toujours positif. J'imagine que ce n'est pas toujours le cas dans les langages informatiques car tous les programmeurs ne sont pas des mathématiciens. Mes deux sous, je considérerais cela comme un défaut de conception du langage, mais vous ne pouvez pas le changer maintenant.
= MOD (-4,180) = 176 = MOD (176, 180) = 176
parce que 180 * (-1) + 176 = -4 identique à 180 * 0 + 176 = 176
En utilisant l'exemple d'horloge ici, http://mathworld.wolfram.com/Congruence.html Vous ne diriez pas duration_of_time mod cycle_length est -45 minutes, vous diriez 15 minutes, même si les deux réponses satisfont aux équation de base.
Voici une alternative:
a < 0 ? b-1 - (-a-1) % b : a % b
Cela peut être ou ne pas être plus rapide que cette autre formule [(a% b + b)% b], si on y songe Il contient une branche qui est généralement mauvaise avec les processeurs modernes, mais utilise une opération de moins modulo.
En fait, cela pourrait certainement être plus lent.
(Edit: Correction de la formule.)