[Perl] Algoritmo per il calcolo approssimato di PI GRECO

Stato
Discussione chiusa ad ulteriori risposte.

imported_BlackLight

Utente Silver
16 Agosto 2007
211
8
1
98
Eccovi uno script in Perl che consente il calcolo della costante matematica PI con un grado di precisione arbitraria decisa dall'utente (attenzione che un numero di passi maggiore di 22 rallenta in modo considerevole il sistema e può potenzialmente esaurire le sue risorse, dato che la complessità dell'algoritmo aumenta in modo esponenziale all'aumentare dei passi da compiere).

Il calcolo della costante numerica irrazionale viene effettuato sfruttando uno stratagemma matematico

intjh1.png


L'integrale viene calcolato approssimativamente con il metodo dei rettangoli. Codice:

Codice:
#!/usr/bin/perl

# Algoritmo per il calcolo approssimato di pi greco attraverso l'approssimazione numerica
# dell'integrale: 4*int [0:1] (1/(1+x²))

@f[100],@a[100],@A[100];
$a1=$A1=$x=0;

print "\nAttenzione: Maggiore sarà il numero di passi di approssimazione, maggiore sarà il tempo\n";
print "che il calcolatore impiegherà a calcolare pi!\n\n";
print "Quanti passi di approssimazione devo effetturare? ";
$steps = <STDIN>;

print "Attendere prego...\n";

if ($steps<1)  {
     print "Numero di passi non valido\n";
     exit(-1);
}

$base = 1/(2**($steps-1));
$f[0] = 1;

for ($i=1; $i<=(2**($steps-1)); $i++) {
     $x += $base;
     $f[$i] = 1/(1+$x*$x);
     $a[$i] = $base*$f[$i];
     $A[$i] = $base*$f[$i-1];
}

for ($i=1; $i<=(2**($steps-1)); $i++) {
     $A1 += $A[$i];
     $a1 += $a[$i];
}

$pi = ($A1+$a1)*2;

print "Approssimazione di pi: ",$pi,"\n";

--EDIT--

Dopo delle richieste su altri forum, ho preparato anche una versione del programma in C:

Codice:
// Algoritmo per il calcolo approssimato di pi greco attraverso l'approssimazione numerica
// dell'integrale: 3*int [0:1] (1/(1+x²))

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

int my_pow(int steps);

main()  {
        double *f,*a,*A;
        double base,pi,a1=0,A1=0,x=0;
        int i,steps;

        printf( "\nAttenzione: Maggiore sarà il numero di passi di approssimazione, maggiore sarà il tempo\n"
                "che il calcolatore impiegherà a calcolare pi!\n\n");

        printf( "Quanti passi di approssimazione devo effetturare? (1-100) ");
        scanf("%d",&steps);

        if ((steps<1) || (steps>100))  {
                printf( "Numero di passi non valido\n");
                return -1;
        }

        f = (double*) malloc (my_pow(steps-1)*sizeof(double));
        a = (double*) malloc (my_pow(steps-1)*sizeof(double));
        A = (double*) malloc (my_pow(steps-1)*sizeof(double));

        base = (float) 1/(my_pow(steps-1));
        f[0] = 1;

        for (i=1; i<=my_pow(steps-1); i++)  {
                x += base;
                f[i] = 1/(1+x*x);
                a[i] = base*f[i];
                A[i] = base*f[i-1];
        }

        for (i=1; i<=my_pow(steps-1); i++) {
                A1 += A[i];
                a1 += a[i];
        }

        pi = (A1+a1)*2;

        printf("Approssimazione di pi: %.40lf\n",pi);
}

int my_pow(int steps)  {
        int i,res=1;

        for (i=0; i<steps; i++)
                res*=2;

        return res;
}

e in Java:

Codice:
import java.io.*;
import java.lang.*;

public class Pi  {
        public static void main (String args[])  {
                float steps=0;
                float a1=0;
                float A1=0;
                float x=0;

                System.out.print ("Numero di passi da effettuare: ");

                try  {
                        DataInputStream in = new DataInputStream (System.in);
                        steps = Float.valueOf(in.readLine()).floatValue();
                }

                catch (Exception e)  {}

                if (steps<1)  {
                        System.out.println ("Numero di steps non valido");
                        System.exit(1);
                }

                float f[] = new float[ (int) Math.pow(2.0,steps)];
                float a[] = new float[ (int) Math.pow(2.0,steps)];
                float A[] = new float[ (int) Math.pow(2.0,steps)];
                float base = 1/( (float) Math.pow(2.0,steps-1));
                f[0] = 1;

                for (int i=1; i<=Math.pow(2.0,steps-1); i++)  {
                        x += base;
                        f[i] = 1/(1+(x*x));
                        a[i] = base*f[i];
                        A[i] = base*f[i-1];
                }

                for (int i=1; i<=Math.pow(2.0,steps-1); i++)  {
                        A1 += A[i];
                        a1 += a[i];
                }

                float pi = (A1+a1)*2;
                System.out.println ("Valore approssimato di PI: " + pi + "\n");
        }
}
 
Stato
Discussione chiusa ad ulteriori risposte.