Thomas Zilliox
Intégrateur CSS Freelance à Lyon

Modulos positifs en JavaScript

J’ai régulièrement un problème avec le fonctionnement des modulos en JavaScript : les modulos de nombres négatifs renvoient un résultat négatif.

3 % 26; // ✔ 3
29 % 26; // ✔ 3
-23 % 26; // ⨯ -23 instead of 3
-49 % 26; // ⨯ -23 instead of 3
-75 % 26; // ⨯ -23 instead of 3

Cela n’est pas forcément un problème. Ici, j’essaie de décoder des messages encodés avec un chiffre Vigenere et quand je décale une lettre « A » (1 dans l’ordre de l’alphabet) de « -1 », je dois obtenir la lettre « Z » (26 dans l’ordre de l’alphabet).

Le fonctionnement des modulos en JavaScript peut être une source régulière de bug, car on ne pense pas forcément à tester notre code avec des nombres négatifs. En plus, un·e développeur·se qui n’est pas habitué·e à JavaScript peut être surpris·e par cette subtilité qui n’existe pas dans tous les autres langages de programmation.

Voici ma solution :

/**
 * Returns the remainder of the division
 *
 * @param {number} number
 * @param {number} divisor
 * @return {number} the remainder
 */
function positiveModulo(number, divisor) {
  return ((number % divisor) + divisor) % divisor;
}

L’astuce ici est de faire un premier modulo pour s’assurer d’avoir une valeur entre « -divisor » et « divisor ». Puis, on ajouter une fois le divisor pour obtenir une valeur entre « 0 » et « 2*divisor », donc forcément positive. Enfin, on réalise le modulo voulu.

Exemples

positiveModulo(3, 26); // ✔ 3
positiveModulo(29, 26); // ✔ 3
positiveModulo(-23, 26); // ✔ 3
positiveModulo(-49, 26); // ✔ 3
positiveModulo(-75, 26); // ✔ 3

Essayez


console.log(-23 % 26);
console.log(positiveModulo(-23, 26));

Amusez-vous bien, Thomas.

That's my face!

Thomas ZILLIOX

L'homme qui murmurait à l'oreille des chevrons.

Je développe, j'intègre, je forme ou je conseille sur les CSS. Besoin d'améliorer la maintenabilité ou les performances de vos projets ?