Partage
  • Partager sur Facebook
  • Partager sur Twitter

mpz_t et exception en point flottant

Sujet résolu
    17 août 2017 à 13:39:21

    Bonjour à tous!

    Voilà, j'utilise pour la première fois des variables de type mpz_t. Pas le choix, hélàs. Ce qui fait que j'utilise également les fonctions qui vont avec....notamment mpz_powm_ui, qui me renvoie une jolie petite erreur "exception en point flottant" (OMG, cette traduction!)

    Après quelques recherches, il semblerait que cela vienne d'une division par zéro. Or, pour autant que je sache, une mise au carré ne fait pas de division par zéro...et l'erreur vient très clairement de cette ligne, aucun doute là dessus. Jusqu'ici j'utilisais mpz_pow_ui, et cela fonctionnait bien, mais j'ai besoin du modulo.

    Alors je me dis que peut-être, quelque part, le modulo fait un zéro, mais mince, zéro au carré ça fait zéro un point c'est tout. Pourquoi donc cette erreur?

    Voilà le bout de code concerné:

    mpz_t x[10][128], z[10][128], Z, X;
    int i, j, w, y=0;
    unsigned long T, Tm[10], T1=0, T0=0, Tquadrat=0;
    for(i=0;i<10;i++)
    {
    	  //Initialisation
    	  mpz_inits(x[i][0],z[i][0]);
    	  mpz_set_ui(x[i][0],10*(i+1));
    	  mpz_set_ui(z[i][0],1);
    	  gmp_printf("X: %Zd\n",x[i][0]);
    	  //Calcul des temps de mise au carré:
    	  for(j=0;j<128;j++)
    	  {
    	  	  mpz_init(x[i][j+1]);
    	  	  Tquadrat+=LITTimeModSquare(x[i][j],n);
    	  	  mpz_powm_ui(x[i][j+1],x[i][j],2,n);
    	  	  
    	  }
    	  Tm[i]=exp_daemon(Z,x[i][0]);		
    	  Tm[i]-=Tquadrat;
              printf("Time %i: %lu", i, *Tm);
              Tquadrat=0;
    }

    L'idée est assez simple: j'ai 10 variables x que j'initialise pour l'instant à 10, 20, 30... 100. Pour chacune de ces variables, je mets au carré 128 fois, en calculant chaque fois le temps nécessaire pour mettre au carré (grâce à la fonction LITTModSquare, qui n'est pas à moins et semble fonctionner). En utilisant mpz_pow_ui, ça marchait bien jusqu'au 10ème calcul environ, parce que ça devient vite très très grand (erreur de segmentation). Voilà pourquoi j'ai besoin du modulo. Je voudrais donc mettre mes x au carré modulo n, n étant aussi un mpz_t initialisé plus tôt (et qui ne change jamais). Le tout sans "exception en point flottant"

    Une idée?

    EDIT:

    Bon, il semblerait que j'ai trouvé l'erreur. Pour une raison que je ne m'explique pas, le fait d'initialiser x et z avec mpz_inits a remis mon n à 0. Si quelqu'un sait pourquoi, j'apprécierais une explication. Quoiqu'il en soit, en faisant l'initialisation en deux lignes, avec mpz_init(x[i][0]) et mpz_init(z[i][0]), ça marche. Je hais gmp.

    -
    Edité par Floria 17 août 2017 à 14:29:51

    • Partager sur Facebook
    • Partager sur Twitter
      18 août 2017 à 8:15:06

      Bonjour,

      Ta question m'intéresse. Pourrais tu poster un exemple de test minimal (main + le problème), et la libraire que tu utilise ? (GMP?)

      Je ne comprends pas ton objectif. Ton code est illisible et très confus. Nomme tes variables correctement et utilise l'auto-complétion de ton IDE/éditeur de texte.

      Ecris d'abord un code qui marche, puis ajoute le temps.

      Ton idée se rapproche-t-elle de ça?

      #include <stdio.h>
      #include <math.h>
      
      int main(void) {
          unsigned long long x[10] = {0};
          long double d[10] = {0.0};
          size_t i = 0, j = 0;
          
          for (i = 1; i <= 10; ++i) {
              x[i] = 10 * i;
              d[i] = 10.0 * i;
          }
          for (i = 0; i < 10; ++i) {
              for (j = 0; j < 128; ++j) {
                  x[i] = (unsigned long long) pow((double)x[i], 2.0);
                  d[i] = powl(d[i], 2.0);
              }
          }
          printf("Unsigned long long..\n");
          for (i = 0; i < 10; ++i) {
              printf("%llu\n", x[i]);
          }
          printf("Long double.\n");
          for (i = 0; i < 10; ++i) {
              printf("%Lf\n", d[i]);
          }
          return 0;
      }
      



      Edit : Lis la doc.

      "Negative exp is supported if an inverse base^-1 mod mod exists (see mpz_invert in Number Theoretic Functions). If an inverse doesn’t exist then a divide by zero is raised."

      https://gmplib.org/manual/Integer-Exponentiation.html

      "Function: void mpz_inits (mpz_t x, ...) : Initialize a NULL-terminated list of mpz_t variables, and set their values to 0."

      https://gmplib.org/manual/Initializing-Integers.html

      Hector;

      • Partager sur Facebook
      • Partager sur Twitter
        28 octobre 2017 à 18:13:38

        Salut,

        le code est considérablement long et fait appel à pas mal de truc, j'ai essayé de le minimaliser au maximum en ne mettant que le point qui posait problème. J'ai laissé dedans des variables inutilisées dans ce point, désolée, mais à part ça les noms de variables sont assez clairs à mes yeux... Tquadrat= temps de mise au carré, Tm=temps max, x=ma variable... à la limite le n du modulo n'est pas évident mais c'est une variable globale posée plus tôt dans le code que je n'ai pas choisie moi-même, et je l'ai expliqué dans mon post donc bon...

        Et mon code est commenté et correctement indenté, je ne vois pas ce qu'il a d'illisible ou confus. Sauf pour quelqu'un ne connaissant pas la librairie gmp à la limite. D'autre part j'explique l'objectif de ce petit bout de code. Quant à l'utilisation d'un éditeur de texte...évidemment que j'utilise un éditeur de texte, d'ailleurs le mien à l'avantage de poser les accolades aux bons endroits (quoi que je n'ai rien contre le fait de les mettre à la fin de la ligne "for" et pas en-dessous, je l'ai fait pendant longtemps). Bref, il me semble suivre toutes ces remarques (on ne peut pas en dire autant de ton code, d'ailleurs....)

        Le code que tu donnes a l'air de bien faire la mise au carré des x, mais en vrai la mise au carré je m'en fiche, je ne m'intéresse qu'au temps de cette mise au carré. Et cette mise au carré fonctionnait correctement jusqu'à l'utilisation du modulo, d'où la certitude que le problème venait de là. Donc j'avais bien, au préalable, écrit un "code qui marche". Puis ajouté le modulo et là seulement constaté le problème.
        Je ne connaît pas la fonction powl donc je ne comprends pas du tout l'intérêt de ton d[i]. Quoi qu'il en soit ça fait beaucoup de lignes de codes pour pas grand chose, à mon avis.

        Enfin, j'ai évidemment lu la doc avant de poster. Plusieurs fois même. Mon problème était que le n (mon modulo), initialisé plus tôt et vérifié, n'était pas égal à 0, donc un inverse aurait dû être trouvé, il n'y aurait pas dû avoir de division par 0. Les variables initialisées étant x et z (donc initialisées à 0, je te l'accorde, mais je leur donnait leur valeur ensuite, et n n'est pas modifié ici), il n'y avait aucune raison pour que mon n devienne ensuite 0.

        Donc, je ne sais pas pourquoi, la fonction inits a non seulement initialisé les x et z demandés, mais également le n qui n'était pourtant pas mis en argument et aurait dû être laissé tranquille. La fonction init a en revanche fonctionné correctement.

        La seule question restante est donc pourquoi ceci:

        int main()
        {
        mpz_t n, x, z;
        mpz_init(n);
        mpz_set_ui(n, 100);
        mpz_inits(x,z);
        gmp_printf("%Zd", n);
        }

        renvoie 0, alors que n a été bien initialisé à 100 et non modifié - en théorie - par l'utilisation de inits(x,z).

        PS: je n'ai pas testé ce bout de code. le problème étant réglé depuis un moment, je n'ai plus accès au programme ni à la librairie gmp. Mais c'est, en minimalisant, le problème survenu. Après le inits(x,z), n est "retombé" à 0, effaçant sa valeur originelle.

        • Partager sur Facebook
        • Partager sur Twitter

        mpz_t et exception en point flottant

        × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
        × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
        • Editeur
        • Markdown