Thomas Zilliox
Expert CSS Freelance à Lyon

Modulo avec minimum et maximum en JavaScript

Parfois on cherche à faire un modulo entre deux valeurs personnalisées. C’est mon cas pour décoder des messages encodés avec un chiffre Vigenere, car nos permutations de lettres ont pour valeur minimum « A », soit « 1 », et non « 0 ».

25 % 26; // ✔ 25
26 % 26; // ⨯ 0 instead of 26
27 % 26; // ✔ 1
0 % 26; // ⨯ 0 instead of 26

Le premier problème des modulos en JavaScript est la possibilité d’obtenir des résultats négatifs, ce sujet a été résolu dans un article précédent et nous utiliserons le solution ici.

/**
 * Returns a value between a minimum and a maximum, using modulo to handle the overflows
 *
 * @param {number} number
 * @param {number} min - the minimum value
 * @param {number} max - the maximum value
 * @return {number} clamped value
 */
function moduloClamp(number, min, max) {
  return positiveModulo(number - min, max + 1 - min) + min;
}
Voir les dépendances
// See https://tzi.fr/js/modulos-positifs
function positiveModulo(number, divisor) {
  return ((number % divisor) + divisor) % divisor;
}

L’astuce ici est d’enlever la valeur minimum avant de réaliser son modulo puis de la rajouter au résultat obtenu. Il y a aussi une petite finesse sur la calcul du diviseur qui doit être max + 1 - min.

Exemples

moduloClamp(25, 1, 26); // ✔ 25
moduloClamp(26, 1, 26); // ✔ 26
moduloClamp(27, 1, 26); // ✔ 1
moduloClamp(0, 1, 26); // ✔ 26
moduloClamp(29, 30, 35); // ✔ 35
moduloClamp(36, 30, 35); // ✔ 30

Essayez


console.log(0 % 26);
console.log(positiveModulo(0, 26));
console.log(moduloClamp(0, 1, 26));

Amusez-vous bien, Thomas.

Thomas ZILLIOX

That's my face!

Je suis un développeur CSS freelance sur Lyon.
En tant qu’expert CSS, on dit parfois que je suis « l’homme qui murmure à l'oreille des chevrons ».

Je suis également le co-créateur de Zupple Escape Game Lyon qui propose une salle d’escape game, des jeux de piste, des team building, de nombreuses énigmes en ligne, et même un podcast. Une aventure extraordinaire, grâce à laquelle il n’y a pas deux jours qui se ressemblent.