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 :

Puissance et modulo


Sujet :

C

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    34
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 34
    Par défaut Puissance et modulo
    Bonjour,

    Je cherche à calculer le modulo d'une puissance. Je me heurte au problème du type avec la fonction pow().

    J'ai beau cherché, mon niveau ne m'a pas permis jusque là à me sortir d'affaire.

    Quelqu'un saurait comment faire ce type d'opération :

    long C = pow(x,y) % n ?

    où x, y et n sont des entiers.

    Merci beaucoup pour votre aide !

  2. #2
    Membre Expert Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    long C = lrint(pow((double)x,(double)y)) % n;

  3. #3
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    désolé mais la fonction lrint est uniquement acceptée/définie dans C99..

    En C non-C99 (un programme C portable n'incluera pas des fonctions spécifiques C99), on peut se servir de la fonction modf :

    http://man.developpez.com/man3/modf.3.php

    http://www.linux-kheops.com/doc/man/...n3/modf.3.html

    et après en tirer le modulo par %

    ou bien directement faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    C = (long)(round(x)) % n
    ou si x dépasse les capacités d'un long, faire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    double d=1.0 ;
    long C ;
     
    while ( (d*n) < x )
         d = d + 1.0 ;
     
    C = (d*n - x);

  4. #4
    Membre Expert Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Par défaut
    Citation Envoyé par souviron34 Voir le message
    désolé mais la fonction lrint est uniquement acceptée/définie dans C99..
    un programme C portable n'incluera pas des fonctions spécifiques C99.
    La norme C99 comme son nom l'indique date de 1999, on est en 2007 faut arrêter maintenant avec ça et se mettre à la page. C'est une ironie de dire qu'un programme qui respecte la norme n'est pas portable...

  5. #5
    Expert confirmé
    Avatar de Skyounet
    Homme Profil pro
    Software Engineer
    Inscrit en
    Mars 2005
    Messages
    6 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Software Engineer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 6 380
    Par défaut
    Citation Envoyé par nicolas.sitbon Voir le message
    La norme C99 comme son nom l'indique date de 1999, on est en 2007 faut arrêter maintenant avec ça et se mettre à la page. C'est une ironie de dire qu'un programme qui respecte la norme n'est pas portable...
    Ouais mais bon gcc ne respecte pas encore entièrement la norme C99 donc on a beau être en 2007 si ton compilateur ne supporte pas entièrement cette norme autant rester avec la norme de 89 qui elle est supportée par gcc (entre autres).

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    34
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 34
    Par défaut
    Ne vous battez pas pour moi

    J'essairai ce soir. Quelle est la solution la plus recommandable ?

  7. #7
    Membre Expert
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Par défaut
    Citation Envoyé par nicolas.sitbon Voir le message
    La norme C99 comme son nom l'indique date de 1999, on est en 2007 faut arrêter maintenant avec ça et se mettre à la page. C'est une ironie de dire qu'un programme qui respecte la norme n'est pas portable...
    C'est ironique mais c'est une realite. Peu de compilateurs implementent C99 en entier (Comeau est sans doute le plus complet). gcc supporte la majeure partie des nouveautes, mais d'autres ont le statut "broken", ce qui n'est pas tres rassurant. Borland et Microsoft ont choisi de ne pas implementer C99 et mettent l'accent sur le C++.
    S'il existe une solution C90 equivalente, il est donc preferable de ne pas utiliser C99.

  8. #8
    Membre Expert Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Par défaut
    Pour moi ça n'est pas logique, mon compilateur implémente C99, dans les autres langages, quand une nouvelle version apparaît les gens ne mettent pas 20 ans pour s'y mettrent, le C a déjà assez mauvaise réputation comme ça, on dis que c'est un langage dépassé, on pourrait prétexté que la dernière révision date de 2005 mais vous vous bloquez sur 1989, et toutes les améliorations et nouvelles fonctionnalités passent aux oubliettes...

  9. #9
    Membre Expert
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Par défaut
    Citation Envoyé par nicolas.sitbon Voir le message
    Pour moi ça n'est pas logique, mon compilateur implémente C99, dans les autres langages, quand une nouvelle version apparaît les gens ne mettent pas 20 ans pour s'y mettrent, le C a déjà assez mauvaise réputation comme ça, on dis que c'est un langage dépassé, on pourrait prétexté que la dernière révision date de 2005 mais vous vous bloquez sur 1989, et toutes les améliorations et nouvelles fonctionnalités passent aux oubliettes...
    Remarque que je n'ai pas dit qu'il ne fallait utiliser C99. J'ai ecrit "S'il existe une solution C90 equivalente, il est donc preferable de ne pas utiliser C99." Cela permet de se reposer sur une base large de compilateurs C90, complets et robustes. Evidemment, on fait se qu'on veut, du moment que le code est clairement documente comme necessitant C99.
    Apres, que des gens disent que le C est un langage depasse, ca les regarde... Il m'arrive souvent de coder en Fortran 77 et, ma foi, il fait le boulot !

  10. #10
    Gf6HqmTW
    Invité(e)
    Par défaut
    Sinon histoire de me la peter en resortant mes cours de term ^^ je passe juste rappeller que le modulo de la puissance est ... le modulo de la puissance du modulo ... c'est pas completement HS

  11. #11
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    Citation Envoyé par nicolas.sitbon Voir le message
    Pour moi ça n'est pas logique, mon compilateur implémente C99
    De quel compilateur s'agit-il? Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  12. #12
    Membre Expert Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Par défaut
    Citation Envoyé par Thierry Chappuis Voir le message
    De quel compilateur s'agit-il? Thierry
    bonjour Thierry, il s'agit de sunstudio 12.
    Cordialement.

  13. #13
    Gf6HqmTW
    Invité(e)
    Par défaut
    Juste pour ma petite methode , le resultat est periodique d'une periodicité inferieur ou egale au diviseur ...

  14. #14
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Je crois que la méthode évoquée par GuJman permet de calculer en entier, en un nombre raisonnable d'opérations avec un résultat exact. Le passage à des flottants par pow peut donner lieu à des erreurs de calculs difficiles à maîtriser.
    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    unsigned int kNMod( unsigned int k, unsigned int N, unsigned int mod)
    {
       // (k^N)mod(mod)
       unsigned int resultat = 1;
       if(mod == 0 || k==0) return 0;   // par sécurité
       k = k % mod;
       while (N != 0)
       {
         if (N & 1) resultat = resultat*k % mod;
         k = k*k %mod;
         N = N/2;
       }
       return resultat;
    }

  15. #15
    Gf6HqmTW
    Invité(e)
    Par défaut
    Alors pour accelerer encore ta methode diogene tu peut garder le premier resultat du modulo que tu calcules pour racourcir encore tout le travaille !
    Perso je ferais comme ca (en repompant largement tes sources ^^)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    unsigned int kNMod( unsigned int k, unsigned int N, unsigned int mod)
    {
       // (k^N)mod(mod)
       unsigned int periode = 0;
       unsigned int Tab[mod-1];
       if(mod == 0 || k==0) return 0;   // par sécurité
       Tab[Periode++] = k % mod;
       If (N != 0)
       {
          while ((N != 0)&&(Tab[Periode-1]!=Tab[0])&&(Periode!=1))
          {
             k=Tab[Periode]
             Tab[Periode++] = k % mod;
             N--;
          }
       N = (N % --Periode)-1;
       }
       return Tab[N];
    }
    Voila c'est plus optimisé ^^

    Je ne sais pas si
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    k=Tab[Periode]
    Tab[Periode++] = k % mod;
    est equivalent à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Tab[Periode++] = Tab[Periode] % mod;

  16. #16
    Membre averti
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    34
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 34
    Par défaut
    N'étant pas très très à l'aise avec le C, quelle solution selon votre expertise, est la meilleure pour mon problème ?

    Merci en tout cas pour vos contributions !

  17. #17
    Membre averti
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    34
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 34
    Par défaut
    Je ne comprend pas le code proposé.

    Par ailleurs pour lrint ça ne compile pas :

    incompatible implicit declaration of built-in function «lrint"


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    #include <stdio.h>
    #include <math.h>
    #include <stdlib.h>
    ...
    long C = lrint(pow((double)M,(double)e)) % n;
    Ca ne me paraît pas incorrect...

  18. #18
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 398
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 398
    Par défaut
    Cela veut typiquement dire que la fonction lrint n'est pas déclarée (bien que gcc la connaisse comme "built-in").
    Il doit y avoir un fichier d'en-tête supplémentaire à inclure...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  19. #19
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par Adrien93 Voir le message
    Je ne comprend pas le code proposé.

    Par ailleurs pour lrint ça ne compile pas :

    incompatible implicit declaration of built-in function «lrint"


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    #include <stdio.h>
    #include <math.h>
    #include <stdlib.h>
    ...
    long C = lrint(pow((double)M,(double)e)) % n;
    Ca ne me paraît pas incorrect...
    lrint n'a pas de declaration, donc elle est declaree implicitement comme retournant un int. Cela fait un conflit avec la version built-in qui retourne un long comme la version standard.

    Le probleme est que math.h ne declare pas lrint, donc c'est soit que tu ne passes pas les bons arguments pour avoir la declaration, soit que tu utilises une bibliotheque qui n'est pas C99.

    Hypothese la plus probable: tu utilises la version de gcc qui utilise la bibliotheque de microsoft et dans ce cas il vaut bien abandonner l'idee d'utiliser la bibliotheque c99.

  20. #20
    Membre averti
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    34
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 34
    Par défaut
    Hmmm, quelle solution s'offre à moi ? J'en perds mes cheveux lol

Discussions similaires

  1. calcul du modulo ou puissance d'un nombre
    Par tcheck_vi dans le forum MATLAB
    Réponses: 2
    Dernier message: 03/06/2009, 07h54
  2. Réponses: 1
    Dernier message: 05/04/2009, 12h29
  3. simplification calcul puissance et modulo
    Par Gotman-B dans le forum Delphi
    Réponses: 5
    Dernier message: 23/05/2007, 18h23
  4. x² et puissance de x par récurrence
    Par olivieram dans le forum Algorithmes et structures de données
    Réponses: 7
    Dernier message: 15/12/2002, 23h59
  5. Besoin d'aide pour l'I.A. d'un puissance 4
    Par Anonymous dans le forum C
    Réponses: 2
    Dernier message: 25/04/2002, 17h05

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