Numeroni e programmazione : la libgmp

Spesso nasce la necessità di effettuare tramite l’elaboratore, calcoli che producono risultati non gestibili dai registri del nostro processore.Un registro di 32 bit ad esempio,non può rappresentare interi con segno che si estendano oltre 2 ³¹ -1 in quanto ci si imbatterebbe in un overflow.
Similmente,anche avendo a disposizione registri a virgola mobile,notiamo che in un moderno calcolatore non possiamo visualizzare in output un numero maggiore di 6 cifre dopo la virgola.Per questo è necessario sfruttare librerie dedicate alla gestione
dei “grandi numeri” e tra queste ho pensato di presentarvi la libgmp,
una libreria GNU che potete scaricare dal sito ufficiale (assieme ad una copiosa documentazione )o dai repository ufficiali della vostra piattaforma GNU/Linux.
Ma non vi voglio lasciare a mani vuote,vi porto un piccolo esempio: l’algoritmo di Archimede per il calcolo approssimato del pigreco.
Ho fatto in modo che l’utente possa scegliere sia la precisione di macchina,che il numero di cifre dopo la virgola stampate,che il numero di cicli da ripetere per approssimare meglio il risultato.
Ovviamente data l’instabilità numerica dell’algoritmo è difficile potere ottenere un numero elevato di cifre corrette dopo la virgola se ci limitiamo a settare una bassa precisione.
Le due cose devono bilanciarsi anche con le risorse del vostro PC, se non volete forzare la terminazione del programma con un kill -9.
Ecco il codice.


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

int main(int argc,char* argv[]){
	int i;
	if(argc != 4){
		printf("Uso : %s precisione_di_macchina   numero_cicli   cifre_dopo_la_virgola\n ",argv[0]);
		return 1;
		}

	mpf_set_default_prec(atoi(argv[1]));
	mpf_t A,l,sin_b,op1,op2,op3,op4,op5; //inizializzo i puntatori alle strutture a virgola mobile
        mpf_init(op1); //inizializzo le strutture puntate
        mpf_init(op2); // gli "op" saranno gli operatori per i risultati intermedi ...
        mpf_init(op3); // ... che devo usare perchè le funzioni aritmetiche della libreria sono funzioni void
        mpf_init(op4);
        mpf_init(op5);
	mpf_init_set_str(l,"2",10); // posso fare un'assegnazione ("2") contestualmente all'inizializzazione
	mpf_init(A);
	mpf_init_set_str(sin_b,"1",10);// il terzo campo serve a scegliere la base
  	printf("precisione %d\n",mpf_get_default_prec()); 	

	for(i=2;i<atoi (argv[2]);i++){           //Signore e signori,l'algoritmo di Archimede come non l'avete visto mai
		mpf_mul(A,l,sin_b);
		mpf_mul_ui(l,l,2);
		 mpf_pow_ui(op1,sin_b,2);
		 mpf_ui_sub(op2,1,op1);
		 mpf_sqrt(op3,op2);
		 mpf_ui_sub(op4,1,op3);
		 mpf_div_ui(op5,op4,2);
		 mpf_sqrt(sin_b,op5);
	}
	mpf_mul(A,l,sin_b);

	gmp_printf("Pigreco troncato a %d cifre dopo la virgola:%d cicli effettuati %.*Ff \n",atoi(argv[3]),atoi(argv[2]),atoi(argv[3]),A); //funzione di libreria per l'output formattato (analogo della printf)

	mpf_clear(A); // uso clear per liberare la heap dei numeroni allocati...
	mpf_clear(l);
	mpf_clear(sin_b);
	mpf_clear(op1);
        mpf_clear(op2);
        mpf_clear(op3);
        mpf_clear(op4);
        mpf_clear(op5);
}

Compiliamo con gcc -l lgmp -o nome_eseguibile nomefile.c
Ecco un possibile output

ordeal@debian:~/Desktop$ ./archimede 50000 2000 600precisione 50016
Pigreco troncato a 600 cifre dopo la virgola:2000 cicli effettuati

3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862
803482534211706798214808651328230664709384460955058223172535940812848111745028410270
193852110555964462294895493038196442881097566593344612847564823378678316527120190914
564856692346034861045432664821339360726024914127372458700660631558817488152092096282
925409171536436789259036001133053054882046652138414695194151160943305727036575959195
309218611738193261179310511854807446237996274956735188575272489122793818301194912983
367336244065664308602139494639522473719070217986094370277053921717629317675238467481
8467669405132
Con un pò di buona volontà e tanta,tanta,tanta potenza di calcolo,riuscirete a fregare anche questi simpatici ragazzi.

Una Risposta a “Numeroni e programmazione : la libgmp”

  1. pupidda79 Dice:

    fantastico come te!

Lascia una Risposta