2017-07-11 5 views
-4

Je voudrais vous demander comment ce code écrit en C serait dans GMP. J'ai essayé quelque chose à écrire mais la bibliothèque est difficile à comprendre. Je ne sais pas comment écrire une opération: r = r*10 + n%10; dans gmp. Je serais très reconnaissant pour l'aide.De C à la mise en œuvre GMP

#include <stdio.h> 
#include <stdlib.h> 
#include <stdbool.h> 
#include <gmp.h> 

long long rev(long long n) 
{ 
    long long r = 0; 
    while (n > 0) 
    { 
     r = r*10 + n%10; 
     n = n/10; 
    } 
    return r; 
} 

bool palindrome(long long n) 
{ 
    return (rev(n) == n); 
} 

void reverseAdd(long long n) 
{ 
    long long r=0; 
    while (n <= 100000000000000) 
    { 
     r = rev(n); 
     printf("stage: %lld + %lld\n",n,r); 

     n = n + r; 

     if (palindrome(n)) 
     { 
      printf("Palindrom: %lld\n",n); 
      break; 
     } 
     else if (n > 100000000000000) 
     { 
      printf("Not a palindrome\n"); 
     } 
    } 
} 


int main() 
{ 
    long long l; 

    printf("Give the number to analyze:"); 
    scanf("%lld",&l); 
    reverseAdd(l); 
    return 0; 
} 
+0

Ne pas oublier d'utiliser des littéraux longs. – Charles

+0

Le nombre décimal '100000000000000000000000000' est hexadécimal' DCC80CD2E4000000' qui correspond seulement au type '** unsigned ** long long' 64 bits. –

+0

Je veux dire que, "n" pourrait être écrit en gmp –

Répondre

0

Pour imprimer mpz_t, utilisez les variables gmp_printf. GMP ajoute les types ‘Z’, ‘Q’ et ‘F’ respectivement pour mpz_t, mpq_t and mpf_t.

The GMP types are: 

F mpf_t, float conversions 
Q mpq_t, integer conversions 
M mp_limb_t, integer conversions 
N mp_limb_t array, integer conversions 
Z mpz_t, integer conversions 

gmp_printf accepte les chaînes de format similaire à la norme C printf (voir Formatted Output dans la bibliothèque GNU C Manuel de référence). En réponse à votre dernière question et à votre programme, vous pouvez utiliser gmp_printf pour imprimer l. Voir le programme modifié ci-dessous:

//.... 

int main() 
{ 
    int k; 
    mpz_t l; 
    mpz_t n; 
    mpz_init (n); /* remember to init mpz variables */ 
    mpz_init (l); 

    printf("Number to analysis: "); 
    gmp_scanf("%Zd",l); 

    gmp_printf ("%s the mpz number %Zd\n", "You have entered", l); 

    do 
    { 
     mpz_set(n, l); 
     analyzeAdd(n); 
     mpz_add_ui(l,l,1); 

    }while(false); 

    gmp_printf ("%s is equal %Zd\n", "Now the n", n); 

    return 0; 
} 

Sortie:

Number to analysis: 123321 
You have entered the mpz number 123321 
Now the n is equal 246642 
0

Vous devez lire quelques tutoriels sur GMP.

Par exemple:

GMP Tutorial

Advanced GMP Tutorial

Code examples per gmp function - mon préféré!

More GMP Examples

Quelques fonctions simples GMP:

mpz_t t; // this is the type of statement is needed to declare a variable 
mpz_init (t); // initialization of a variable 
mpz_set_ui (t, 2); // assignment of 2 to already initialized variable t 
mpz_set_str (t, "1234"); // string assignment 
mpz_add (t, a , b); // a + b is assigned to t, that is, t = a + b 
mpz_sub (t, a, b); // subtraction 
mpz_mul (t, a, b); // multiplication 
gmp_printf ("% Zd ", t); // print output t 

Un simple programme GMP:

#include <gmp.h> 
#include <stdio.h> 
#include <assert.h> 

int main(){ 

    /* The basic operation is to initialize the number */ 
    /* 1. Initialize the number r */ 
    mpz_t r; 
    mpz_init(r); 
    mpz_set_ui(r,15); /*r = 15 now */ 

    mpz_mul_ui(r,r,10); /* r = r * 10 */ 

    printf (" r = "); 
    mpz_out_str(stdout,10,r); 
    printf ("\n"); 

} 

r = r * 10 + n % 10; doit être fait par étapes:

mpz_mul_ui(r,r,10); /* r = r * 10 */ 

mpz_mod_ui(n,n,10); /* n = n % 10 */ 

mpz_add(r,r,n);  /* r = r + n */ /* r = r * 10 + n % 10 */ 

mpz_t variable peut être utilisée comme paramètre de fonction.

Je cite la documentation: Lorsqu'une variable de type mpz_t est utilisé en tant que paramètre de fonction, il est effectivement un appel par référence, ce qui signifie quoi que ce soit la fonction ne lui sera être faite à l'original dans l'appelant. Lorsqu'une fonction va renvoyer un résultat mpz_t, elle doit fournir un paramètre distinct ou des paramètres qu'elle définit, comme le font les fonctions de la bibliothèque GMP. Un retour d'un mpz_t ne renvoie pas l'objet, seulement un pointeur, et ce n'est certainement pas ce que vous voulez. Tout cela s'applique à mpq_t et mpf_t aussi.

Voici un exemple de fonction acceptant un paramètre mpz_t, effectuant un certain calcul et renvoyant un résultat.

void 
myfunction (mpz_t result, mpz_t param, unsigned long n) 
{ 
    unsigned long i; 

    mpz_mul_ui (result, param, n); 
    for (i = 1; i < n; i++) 
    mpz_add_ui (result, result, i*7); 
} 

int 
main (void) 
{ 
    mpz_t r, n; 
    mpz_init (r); 
    mpz_init_set_str (n, "123456", 0); 

    myfunction (r, n, 20L); 
    mpz_out_str (stdout, 10, r); printf ("\n"); 

    return 0; 
} 

Cet exemple fonctionnera si result et param sont la même variable, tout comme les fonctions de la bibliothèque. Mais parfois, cela est difficile à organiser, et une application peut ne pas vouloir se soucier de ses propres sous-programmes.

Exemple: Comment inverser le numéro à l'aide GMP:

void rev(mpz_t r, mpz_t param, mpz_t n) 
{ 
    mpz_t nm10;  /* introduce temporary variable to hold n%10 result */ 
    mpz_init (nm10); /* init */ 

    mpz_set_ui(r,0); /* set r to 0 */ 

    /* Call mpz_cmp_ui to compare op1 and op2.      */ 
    /* Return a positive value if op1 > op2, zero if op1 = op2,  */ 
    /*   or a negative value if op1 < op2      */ 
    /*                 */ 

    while (mpz_cmp_ui(n,0) > 0) /* Call mpz_cmp_ui to compare op1 and op2 */ 
    { 
     mpz_mul_ui(r,param,10); /* r = r * 10 */ 

     mpz_mod_ui(nm10,n,10); /* nm10 = n%10 */ 

     mpz_add(r,r,nm10);  /* r = r*10 + n%10; */ 

     mpz_div_ui(n,n,10);  /* n = n/10 */ 
    } 
} 

void reverseAdd(mpz_t n) 
{ 
     mpz_t r; 
     mpz_init (r); 

     mpz_set_ui(r,0); 

     mpz_out_str(stdout,10,n); printf (" n: input value \n"); 

     rev(r, r, n); 

     mpz_out_str(stdout,10,n); 
     printf ("  n: after calculations value \n"); 

     mpz_out_str(stdout,10,r); 
     printf (" r: reversed value\n"); 

} 

int main() 
{ 
    mpz_t l; 
    mpz_init (l); 

    printf("Give number to analyze:"); 
    gmp_scanf("%Zd",l); 

    reverseAdd(l); 

    return 0; 
} 

SORTIE:

Give number to analyze:12345 
12345 n: input value 
0  n: after calculations value 
54321 r: reversed value 

Exemple: Vérifiez si le numéro donné est un palindrome:

void rev(mpz_t r, mpz_t param, mpz_t n) 
{ 
    mpz_t nm10;  /* introduce temporary variable to hold n%10 result */ 
    mpz_init (nm10); /* init */ 

    mpz_set_ui(r,0); /* set r to 0 */ 

    while (mpz_cmp_ui(n,0) > 0) /* Call mpz_cmp_ui to compare op1 and op2 */ 
    { 
     mpz_mul_ui(r,param,10); /* r = r * 10 */ 
     mpz_mod_ui(nm10,n,10); /* nm10 = n%10 */ 
     mpz_add(r,r,nm10);  /* r = r*10 + n%10; */ 
     mpz_div_ui(n,n,10);  /* n = n/10 */ 
    } 
} 

void analyze(mpz_t n) 
{ 
     mpz_t r; 
     mpz_init (r); 

     mpz_t input; 
     mpz_init (input); 

     mpz_set(input, n); /* remember the input */ 

     mpz_out_str(stdout,10,n); 
     printf (" n: input value \n"); 

     rev(r, r, n); 

     mpz_out_str(stdout,10,r); 
     printf (" r: reversed value value\n"); 

     if ( mpz_cmp(input,r) == 0) { 
      mpz_out_str(stdout,10,input); 
      printf(" is a Palindrome! \n"); 
     } 
     else{ 
      printf("The input number was not a Palindrome.\n"); 
     } 
} 

int main() 
{ 
    mpz_t l; 
    mpz_init (l); 

    printf("Give number to analyze: "); 
    gmp_scanf("%Zd",l); 

    analyze(l); 

    return 0; 
} 

SORTIE:

Give number to analyze: 123454321 
123454321 n: input value 
123454321 r: reversed value value 
123454321 is a Palindrome! 

Ceci est équivalent au code C de Marianna utilisant l'implémentation boucle et GMP:

void rev(mpz_t r, mpz_t n) 
{ 
    mpz_t nm10;  /* introduce temporary variable to hold n%10 result */ 
    mpz_init (nm10); /* init */ 

    mpz_t nn; 
    mpz_init (nn); /* init */ 

    mpz_set(nn, n); /* do not use n directly, use nn for divisions '/' */ 
    mpz_set_ui(r,0); /* set r to 0! */ 

    while (mpz_cmp_ui(nn,0) > 0) /* Call mpz_cmp_ui to compare op1 and op2 */ 
    { 
     mpz_mul_ui(r,r,10);  /* r = r * 10 */ 
     mpz_mod_ui(nm10,nn,10); /* nm10 = n%10 */ 
     mpz_add(r,r,nm10);  /* r = r*10 + n%10; */ 
     mpz_div_ui(nn,nn,10); /* n = n/10 */ 
    } 
} 

bool palindrome(mpz_t r, mpz_t n) 
{ 
    /* calculate the reverse number */ 
    rev(r, n); 
    return((mpz_cmp(r,n) == 0)); 
} 

void analyzeAdd(mpz_t n) 
{ 
    mpz_t r; 
    mpz_init (r); 

    mpz_set_ui(r,0); /* set r to 0! */ 

/* loop */ 

    while (1) 
    { 
     int compare = mpz_cmp_ui(n,100000000000000); 
     /* Return a positive value if op1 > op2, zero if op1 = op2,  */ 
     /* or a negative value if op1 < op2        */ 

     if (compare > 0) 
     { 
     printf("Not a palindrome!\n"); 
     break; /* break the while loop */ 
     } 

     rev(r, n); /* r is returned, n is not modified */ 

     printf("stage: "); 
     mpz_out_str(stdout,10,n); 
     printf(" + "); 
     mpz_out_str(stdout,10,r); 
     printf("\n"); 

     /* !!! */ 
     mpz_add(n,n,r); /* n = n + r; */ 


     if (palindrome(r,n)) 
     { 
      printf("Palindrome: "); 
      mpz_out_str(stdout,10,n); 
      printf("\n"); 

      break; 
     } 
     else if (mpz_cmp_ui(n,100000000000000) > 0) 
     { 
      printf("Not a palindrome\n"); 
     } 
    }/*while*/ 
} 

int main() 
{ 
    mpz_t l; 
    mpz_init (l); 

    printf("Give number to analyze: "); 
    gmp_scanf("%Zd",l); 

    analyzeAdd(l); 

    return 0; 
} 

SORTIE:

a)

Give number to analyze: 77 
stage: 77 + 77 
stage: 154 + 451 
stage: 605 + 506 
Palindrome: 1111 

b)

Give number to analyze: 123456788999000 
Not a palindrome! 
+0

Mais comment écrire ceci "r = r * 10 + n% 10;" en gmp? –

+0

@MariannaKalwat "r = r * 10 + n% 10;" ajouté ci-dessus. – sg7

+0

Je ne savais pas que cela devait être en plusieurs étapes. Merci;) Mais je ne sais pas quoi faire avec "long long rev (long long n)"? –

0

Je voulais que le programme montrerait SORTIE lorsque k> 20 comme celui-ci, par exemple:

Number: 89 Number of stage: 24 Palindrome: 8813200023188 

Et il est ok parce que k = 24.

#include <stdio.h> 
#include <stdlib.h> 
#include <stdbool.h> 
#include <math.h> 
#include <gmp.h> 

void rev(mpz_t r, mpz_t n) 
{ 
    mpz_t nm10; 
    mpz_init (nm10); 

    mpz_t nn; 
    mpz_init (nn); 

    mpz_set(nn, n); 
    mpz_set_ui(r,0); 

    while (mpz_cmp_ui(nn,0) > 0) 
    { 
     mpz_mul_ui(r,r,10);  /* r = r * 10 */ 
     mpz_mod_ui(nm10,nn,10); /* nm10 = n%10 */ 
     mpz_add(r,r,nm10);  /* r = r*10 + n%10; */ 
     mpz_div_ui(nn,nn,10); /* n = n/10 */ 
    } 
} 

bool palindrome(mpz_t r, mpz_t n) 
{ 
    rev(r, n); 
    return((mpz_cmp(r,n) == 0)); 
} 

void analyzeAdd(mpz_t n) 
{ 
    mpz_t l; 
    mpz_t r; 
    mpz_init (r); 

    mpz_set_ui(r,0); 

    int k = 0; 

    while (1) 
    { 

     k = k + 1; 

     if (k > 400) 
     { 
     /*printf("It's not a palindrome!\n");*/ 
     break; 
     } 

     rev(r, n); 

     /*printf("Krok: "); 
     mpz_out_str(stdout,10,n); 
     printf(" + "); 
     mpz_out_str(stdout,10,r); 
     printf("\n");*/ 


     mpz_add(n,n,r); /* n = n + r; */ 


     if (palindrome(r,n)) 
     { 
      if (k > 20) { 
      printf("Number of stage: %d ",k); 
      printf("Palindrome: "); 
      mpz_out_str(stdout,10,n); 


      printf("\n"); 
      } 

      break; 
     } 
    } 
} 

int main() 
{ 
    mpz_t l; 
    mpz_t n; 
    mpz_init (l); 

    printf("Give number: "); 
    gmp_scanf("%Zd",l); 

do 
{ 
     mpz_set(n, l); 
     gmp_printf("Number: %Zd \n",l); 
     analyzeAdd(n); 
     mpz_add_ui(l,l,1); 


}while(1); 



    return 0; 
}