[172 vues] 2022-02-01 Emmanuel Orchanian
NOTE : cet article a été affiché dans sa langue originale.
Spoiler
-1 % 30 = -1
-1 % 30 = +29Sommaire
- Par où commencer ?
- Définition du modulo
- Avantages
- Problèmes
- Comment j'ai constaté ce problème ?
- Vocabulaire
- Pourquoi y a-t-il deux type de modulo en programmation ?
- Graphiques
- Modulo "mathématique"
- Modulo "cyclique"
- Modulo euclidien
- On s'en fiche si le diviseur est négatif
- Formules
- Liens
- Notes de la fin
Par où commencer ?
Ben c'est un article pour les matheux.voilà, en plus c'est à propos d'un des sujets les plus ennuyants et ennuyeux pour les codeurs : le modulo...
Définition du modulo
On dit que c'est le reste de la division.
Par exemple "10 divisé par 4 ça fait 2, et il reste 2"
Ainsi l'informaticien va dire "10 modulo 4 donne 2"
Avantages
Pourquoi utilise-t-on le modulo en programmation ? Cela donne un caractère cyclique
(X%30)
Par exemple si j'ai 24h dans une journée et qu'il est 23h, si je rajoute 10h, il ne sera pas "33h" mais 9h, on peux ainsi faire (23 + 10) % 24 = 33 % 24 = 9
Problème
Si on poursuit la même logique dans les négatifs, les résultats changent en fonction du langage ou des outils qu'on utilise.
Comment j'ai constaté ce 😡 problème ?
J'utilise beaucoup la calculatrice de Google pour tester mes calculs (il suffit de taper un calcul dans la barre de recherche Google), en déboguant du PHP, je voulais le modulo d'un angle négatif par rapport à 360°, et je n'arrivais pas à trouver. Après m'être arraché les cheveux, j'ai appris avec aberration que la calculatrice Google m'avait trahi et donnait un autre résultat que PHP... Puis j'ai appris qu'il existait plusieurs modulo en informatique !
Les deux types de modulo en programmation
Saviez-vous que JavaScript et Python n'ont pas le même modulo quand on va dans les négatifs ?
Personnellement je les apelle "modulo mathématique et modulo cyclique".
Vocabulaire
dividende % diviseur
Pourquoi deux types de modulo en programmation ?
Les nombres négatifs posent problème (comme d'habitude), que ce soit le dividende ou le diviseur qui soit négatif, ou les deux...
- Le premier type respecte la définition mathématique "traditionnelle"
- Le deuxième type préfère le pragmatisme en continuant le caractère cyclique dans les négatifs.
-1 % 30 = -1
-1 % 30 = +29Graphiques
x % 30
Modulo avec un nombre positif
x % -30
Modulo avec un nombre négatif (utilisation très rare !)
Modulo "mathématique" JavaScript / PHP
(Modulo de la troncature de la partie décimale)
Le modulo est calculé comme si tout était positifs
À la fin, si le dividende (opérande de gauche) est négatif, alors le résultat est négatif
On s'en fiche du signe du diviseur (opérande de droite), preuve en est, les deux courbes sont les mêmes.
1 % 30 = 1
-1 % 30 = -1
1 % -30 = 1
-1 % -30 = -1
Modulo "cyclique" recherche Google, Python (Modulo de la partie entière)
Le modulo est compris en zéro et le diviseur, donc il a un côté cyclique
et si le diviseur est négatif, tout est négatif.
1 % 30 = 1
-1 % 30 = 29
1 % -30 = -29
-1 % -30 = -1
Modulo euclidien (pas important)
Pareil que le cas précédent (modulo de la partie entière) sauf que tout est positif.
Celui-ci je ne l'ai pas trouvé en informatique.
1 % 30 = 1
-1 % 30 = 29
1 % -30 = 29
-1 % -30 = 1
On s'en fiche si le diviseur est négatif
En pratique, ce sera le dividende (l'opérande de gauche) qui pourra souvent aller dans les négatif, notre diviseur sera souvent statique.
- diviseur = 24 pour les heures
- diviseur = 360 pour les angles
- diviseur = 7 pour les jours
Donc toute la partie de droite dans les graphique ci-dessus n'est pas importante.
Astuce pour savoir quel modulo utilise notre langage ?
Faites-1 % 30 Si ça donne
-1, alors vous avez un modulo "mathématique" Si ça donne
29, alors vous avez un modulo "cyclique"
Formules
Modulo mathématique en cyclique
La plupart du temps le codeur va vouloir avoir un modulo cyclique à partir d'un langage qui pratique un modulo mathématique.
function modCycl(a,b){
return ((a%b)+b)%b;
}
function mod_cycl(a,b){
return ((a%b)+b)%b;
}
Cas rare et souvent inutile
Vous voulez avoir un résultat toujours positif même si le diviseur est négatif ? Il faut transformer en modulo euclidien en appliquant la valeur absolue.
function modCycl(a,b){
return Math.abs(((a%b)+b)%b);
}
function mod-cycl(a,b){
return abs(((a%b)+b)%b);
}
Liens
Voici de bons liens qui m'ont aidé à trouver les mots et apprécier quelque notions mathématiques.
- Explique que .Net utilise aussi le modulo Euclidien https://www.rudyhuyn.com/blog/2013/09/23/modulo-dans-tous-ses-etats/
- La page Wikipédia explique bien, en plus ça contient la liste des langages selon les modulos ! https://fr.wikipedia.org/wiki/Modulo_(op%C3%A9ration)
- GeoGebra m'a aidé à avoir des beaux graphiques (j'ai dessiné les courbes pas dessus) https://www.geogebra.org/graphing?lang=fr
- Ce site détaille bien chaque cas pour les développeurs JavaScript https://blog.smarchal.com/modulo-en-js
Division par zéro
Normalement quand on divise un nombre par zéro, c'est interdit par les mathématiques, mais certains développeurs préfèrent préciser que si on divise par zéro, ça donne zéro. Dans ce cas ne pas oublier de rajouter cette condition dans les fonctions précédentes :
if(b==0) return 0 ; // en premiere ligne de la fonction
Note de la fin
Sans vouloir pleurer c'est un article qui m'a demandé beaucoup de temps à écrire (j'ai voulu être le plus compréhensible possible !), environ 6h à faire toutes les images, réfléchir à comment expliquer...
Un simple commentaire sur Linkedin m'aidera à augmenter le référencement, merci à vous !
Merci d'avoir lu !
Si en général vous avez une question, une curiosité, n'hésitez pas me contacter.