web-dev-qa-db-fra.com

Le meilleur moyen de faire en sorte que le module Java se comporte comme il se doit avec des nombres négatifs?

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
87
fent

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).

121
Peter Lawrey

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
74
John Krueger

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.

9
Ibrahim Arief

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.

7
Chris Golledge

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.)

0
Stefan Reich