IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

résultat de l'opérateur % modulo - python et c


Sujet :

C

  1. #1
    Membre éclairé

    Inscrit en
    Août 2007
    Messages
    308
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 308
    Billets dans le blog
    1
    Par défaut résultat de l'opérateur % modulo - python et c
    Bonjour à tous,

    Pouvez-vous me dire svp pourquoi le résultat de l'opérateur % de l'exemple suivant est différent en c de ce que j'obtiens avec le langage python

    en c : -2%26---> -2
    en python: -2%26 ---> 24

    ça devrait normalement retourner le même résultat mathématiquement parlant non?

    Merci

  2. #2
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 746
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 746
    Par défaut
    La raison est facile à trouver : Modulo, source wiki

    Il y a 2 modes de calcul :
    1. en utilisant la partie entière (définition mathématique) -> dont le Python
    2. en utilisant la fonction de 'troncature de la partie décimale' (approximation de programmation) -> dont le C

    Le wiki n'est pas très clair/ assez succint (ou c'est moi ), mais il faut creuser pour + des précisions mais l'explication est là.

    Et pour moi , le C est plus cohérent : -2 = 26 x 0 - 2 que -2 = 24 - 1 x 26.

    Pour finir, le modulo en C et C++ avec des nombres négatifs, il faut se méfier : depuis ISO C99. En ISO C90, en cas d'opérande négatif, le signe du résultat était défini par l'implémentation.
    Donc en théorie pas trop de problèmes (la norme C99 est quand même très répandue), mais on ne se sait jamais

  3. #3
    Membre éclairé

    Inscrit en
    Août 2007
    Messages
    308
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 308
    Billets dans le blog
    1
    Par défaut
    Merci pour votre réponse.

  4. #4
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 746
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 746
    Par défaut
    Je reviens parce que, après relecture , le problème ce sont les modulos avec des nombres négatifs

    C'est écrit sur le wiki partie entière et partie fractionnaire :
    La partie entière ne doit pas être confondue avec la troncature à l'unité, ou troncature entière, qui correspond à la suppression des décimales en notation usuelle et qui diffère de la partie entière pour les nombres négatifs.

    Par exemple, la partie entière de –1,5 vaut –2, tandis que sa troncature à l'unité vaut –1.
    Et l'autre truc, c'est le signe du modulo : soit le signe du diviseur (définition mathématique) soit le signe de la dividende (troncature).

    Dans mon lien wiki de mon premier message , c'est dit que la FAQ de Python le dit explicitement avec 1 fameux exemple (avec 1 calcul antihoraire, donc négatif) :
    « si une horloge indique 10 heures, qu'indiquait-elle 200 heures avant ? -190 % 12 == 2 est utile ; -190 % 12 == -10 est un bug prêt à mordre. »

    Pour finir, le modulo en C et C++ avec des nombres négatifs, il faut se méfier parce qu'ils utilisent la troncature.

  5. #5
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 799
    Billets dans le blog
    1
    Par défaut
    Bonjour

    Le principal souci c'est que le modulo n'est pas une opération mathématique de base (comme addition etc) mais est construit comme le reste d'une division incomplète. Tant que la division fait intervenir des nombres positifs ça va, mais quand on entre dans le domaine du négatif, les soucis (qui ne dépendent que de l'interprétation que l'on fait du reste) commencent. Et c'est dû essentiellement au fait que -2/26 égal 2/(-26) mais -2%26 n'est plus égal à 2%(-26). Et quand on a un souci d'interprétation, on est obligé alors d'établir des conventions, c'est à dire de règles artifiellement créées pour répondre aux questions les plus fréquentes mais qui trouveront leurs limites pour des questions de détail. Et quand on bascule en programmation on arrive alors sur d'autres soucis qui dépendent de la façon dont les programmeurs auront implémenté ces conventions dans leur langage.
    Le lien wiki dit que le modulo prend le signe exclusif de l'opérande gauche sans tenir compte de l'opérande droite. Donc 117%17=15 mais -117%-17=-15 (et là on dévie clairement de la division où -117/-17=117/17). Mais cette convention permet de vérifier la loi x%n=(x+n)%n (arithmétique de l'horloge où si on rajoute un tour de plus à la petite aiguille cela ne change pas la position de la grande aiguille). C'est aussi comme cela que Python (plus récent que le C) a implémenté cette opération (j'ai tapé les 4 exemple du lien wiki). Et c'est aussi ainsi que Excel calcule (si on veut trouver d'autres comparateurs). Mais malheureusement pas en C qui (peut-être est-ce dû à son âge) a préféré privilégier une autre loi qui dit que x mod −y = x mod y et où, pour lui, -2%26 = -2%-26=-2.

    Il existe d'autres exemples plus ou moins connus en maths d'extrapolation artificielle. Par exemple la factorielle de n suppose n entier. Mais Euler a étendu cette opération sur les nombres décimaux au travers d'une intégrale nommée "gamma" qui d'une part conserve les valeurs des factorielles de nombres entiers (c'est la base) mais qui, d'autre part, permet de faire un lissage continu entre les valeurs des factorielles de "n" et "n+1". Par exemple factorielle(3.5) = gamma(4.5) = 11.63 (nombre effectivement compris entre 6 et 24) et de façon plus générale, factorielle(n) = gamma(n+1) (n appartenant à R). Et donc ces extrapolations ne sont pas toujours implémentées. Par exemple le module math de Python connait les deux fonctions "factorielle" et "gamma" mais n'a pas implémenté la factorielle pour qu'elle accepte des décimaux en transformant le calcul de fact(n) en gamma(n+1). Quand au C qui ne connait même pas la factorielle...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. opérateur modulo et printf
    Par binome-x dans le forum C
    Réponses: 3
    Dernier message: 13/08/2014, 11h47
  2. Opérateur Modulo avec float
    Par Vice555 dans le forum C++
    Réponses: 4
    Dernier message: 29/01/2014, 21h02
  3. Réponses: 4
    Dernier message: 16/02/2010, 12h05
  4. Translation Modulo Python en VB6
    Par Clo72 dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 02/11/2009, 08h07
  5. Opérateur modulo en informix
    Par GBAGO dans le forum Informix
    Réponses: 2
    Dernier message: 27/06/2006, 13h11

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo