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!
Ne pas oublier d'utiliser des littéraux longs. – Charles
Le nombre décimal '100000000000000000000000000' est hexadécimal' DCC80CD2E4000000' qui correspond seulement au type '** unsigned ** long long' 64 bits. –
Je veux dire que, "n" pourrait être écrit en gmp –