02. Es. svolto: pi greco

Il seguente esempio mostra come sia possibile, a partire da una sequenza pseudocasuale, calcolare in modo statistico pi greco.

Consideriamo un quadrato di lato 2 nel quale sia iscritto un cerchio di raggio 1.

Il rapporto delle aree banalmente sarà:

  • Aq/Ac = 4/pi (l'area del quadrato è 2*2=4 mentre l'area del cerchio è 1*1*pi= pi)

da cui:

  • pi = 4 * Ac/Aq

Se utilizziamo la nostra figura come un bersaglio su cui sparare in modo casuale, assumendo che i colpi si distribuiranno uniformemente su tutta la superficie, dovremo approssimativamente avere che:

  • Lq/Lc = 4/pi

da cui:

  • pi = 4 * Lc/Lq

(Lq Lanci che colpiscono il quadrato, Lc Lanci che colpiscono il cercio)

Il seguente programma genera casualmente delle coordinate (x, y) (con 0<= x <=1 e 0<= y <=1) e contabilizza quante rientrano nel primo quadrante del cerchio goniometrico. In base alla formula pi = 4 * Lc/Lq calcola un valore statistico di pi greco.

Notare che, nel programma, Lq coincide con il numero di lanci.


#include <stdio.h>

#include <stdlib.h>

#include <time.h>

#define LANCI 999999

#define PRECISIONE 32767

int main()

{

int i, centri;

float x, y, pi;

srand(time(NULL));

centri=0;

for(i=0; i<LANCI; i++){

x=(float)(rand()%PRECISIONE)/PRECISIONE;

y=(float)(rand()%PRECISIONE)/PRECISIONE;

if((x*x+y*y)<=1.0)

centri++;

}

pi=(float)(4*centri)/LANCI;

printf("pi=%f\n", pi);

return 0;

}

#define LANCI 999999

#define PRECISIONE 32767

Le istruzioni precedenti definiscono due costanti utilizzate nel programma.

La prima fa riferimento al numero di lanci: per avere un risultato significativo è necessario disporre di un campione statistico sufficientemente ampio.

La costante PRECISIONE determina la variabilità delle coordinate.

Si ricorda che il più grande numero generato dalla funzione rand() normalmente è proprio 32767.

Le istruzioni

x=(float)(rand()%PRECISIONE)/PRECISIONE;

y=(float)(rand()%PRECISIONE)/PRECISIONE;

fanno sì che le variabili x e y contengono un valore compreso tra 0 e 1.

Ad esempio, se rand() genera il numero 14472 (numero scelto in modo del tutto arbitrario) si ha:

x = (14472 % 32767) / 32767 = 14472 / 32767 = 0.441663

if((x*x+y*y)<=1.0)

Per il teorema di Pitagora la distanza dal centro di un punto appartenente al primo quadrante è data da SQRT(x^2+y^2). Il punto appartiene al cerchio se la distanza è minore o uguale a 1, cioè:

    • SQRT(x^2+y^2) <= 1 <=> x^2+y^2 <= 1

Quindi la condizione dell'if è verificata se il punto appartiene al cerchio.