Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 13

Discussione: [Java] pigreco

  1. #1

    [Java] pigreco

    Devo fare quest'esercizio :


    Scrivere un programma capace di stampare il pigreco alla precisione di n cifre decimali

    La formula per calcolare il pigreco è :

    pigreco=sommatoria (da 0 a infinito) di (-1)^n*(4/(2n+1))
    avete qualche suggerimento?? :master:

    ps: non voglio la soluzione...vorrei arrivarci da solo...cerco solo consigli e suggerimenti su comme arrivarci!
    E' tutta colpa di Berlusconi !
    Help [Ciclico] Fisco, domande varie

    Avatar

  2. #2
    bè, se vuoi solo un suggerimento pensa al modo più ovvio che c'è per un programmatore di implementare una sommatoria di n termini..

    inizia con ci e finisce con lo

    ciao!!

  3. #3
    Originariamente inviato da mauri@como
    bè, se vuoi solo un suggerimento pensa al modo più ovvio che c'è per un programmatore di implementare una sommatoria di n termini..

    inizia con ci e finisce con lo

    ciao!!
    ciclo?

    onestamente c'avevo pensato ma non funziona...con un ciclo ottengo un pigreco con infinite cifre decimali...invece voglio un pigreco con n cifre decimali!
    E' tutta colpa di Berlusconi !
    Help [Ciclico] Fisco, domande varie

    Avatar

  4. #4
    scusami, ho letto male il tuo problema..

    se questa volta l'ho interpretato bene:
    il tuo programma dovrebbe prima calcolare il pigreco (e qui il suggerimento di prima è ok) poi stamparlo con n cifre decimali, che però non c'entrano niente con l'indice n della sommatoria (forse è qui che c'è un dubbio da risolvere).

    pensa a come potresti memorizzare un numero di n cifre in una struttura dati, con n scelto da te a posteriori (cioè dopo aver lanciato il programma)

    spero di eesere stato d'aiuto questa volta

    ciao

  5. #5
    Originariamente inviato da mauri@como
    scusami, ho letto male il tuo problema..

    se questa volta l'ho interpretato bene:
    il tuo programma dovrebbe prima calcolare il pigreco (e qui il suggerimento di prima è ok) poi stamparlo con n cifre decimali, che però non c'entrano niente con l'indice n della sommatoria (forse è qui che c'è un dubbio da risolvere).

    pensa a come potresti memorizzare un numero di n cifre in una struttura dati, con n scelto da te a posteriori (cioè dopo aver lanciato il programma)

    spero di eesere stato d'aiuto questa volta

    ciao
    Ho chiesto al prof ulteriori chiarimenti sull'esercizio e mi ha detto che devo calcora la precisione tramite questa formula :

    |il valore del n elemento della successione-il valore del n-1 elemento della successione|<10^-n



    in parole povere il pseudocodice di questo prg è :

    1. leggere il valore di n
    2. calcolare epsilon
    2.1 inizializzo epsilon = 0.1
    2.2 per n volte epsilon=epsilon/10
    3 calcolo il primo e il secondo elemento della serie
    4 imposto m=2
    5. finchè |il valore del n elemento della successione-il valore del n-1 elemento della successione|<epsilon
    5.1 il valore del n-1 elemento della successione=il valore del n elemento della successione
    5.2 calcolo il nuovo valore del m elemento della successione
    5.3 incremento m
    6 stampo il risultato

    francamente non c'ho capito niente....e cercavo in questo forum soluzione alternative a quel pseudocodice o qualche anima pia che mi spieghi il tutto!!!
    E' tutta colpa di Berlusconi !
    Help [Ciclico] Fisco, domande varie

    Avatar

  6. #6
    -> 2. calcolare epsilon

    Epsilon serve per calcolare il grado di precisione, non è altro che 10^-n. Se ho una sommatoria che crea questi risultati parziali:

    p1 = 5.61346
    p2 = 5.62953
    p3 = 5.61534
    p4 = 5.61275
    p5 = 5.61187
    (...)

    è chiaro (dal momento che la serie è convergente) che il numero cercato sarà del tipo

    5.61*******

    dunque se cerchi una precisione pari a due cifre decimali basta che il modulo della differenza di due risultati parziali (nell'esempio |p4-p3|=0.00259) sia minore di 0.01 = 10^-2.

    Qui non sono d'accordo con il tuo professore: il modulo della differenza deve essere fatto su due risultati parziali e non su due elementi della sommatoria.

    -> 3 calcolo il primo e il secondo elemento della serie

    primo elemento = (-1)^0*(4/(2*0+1))
    secondo elemento = (-1)^1*(4/(2*1+1))

    -> 4 imposto m=2
    m rapppresenta l'indice del prossimo termine. Avendo calcolato i termini per n = 0 e n = 1 l'indice del prossimo termine sarà n = 2.

    -> 5
    Poi finchè non si raggiunge il grado di precisione voluto (finchè il modulo della differenza di due sommatorie parziali non è minore di epsilon) si calcola il prossimo termine e lo si usa per calcolare la nuova sommatoria parziale.

    Questa è una possibile implementazione. Non tiene conto della lettura di n è probabilmente non segue le convenzioni del codice adottate dal tuo prof

    codice:
    class PiGreco {
        public static void main(String[] args) {
            System.out.println(piGreco(4));
        }
    
        private static double piGreco(int n) {
    
            double epsilon,nElemento,nMenoUnoElemento;
            double piGreco,piGrecoPrecedente;
            int m;
            // 2. calcolare epsilon
            // 2.1 inizializzo epsilon = 0.1
            epsilon = 0.1;
            // 2.2 per n volte epsilon=epsilon/10
            for(int i = 0; i < n; i++) {
                epsilon /= 10;
            }
    
            // 3 calcolo il primo e il secondo elemento della serie
            nMenoUnoElemento = 4.0;     // (-1)^0*(4/(2*0+1))
            nElemento = -4.0/3.0;       // (-1)^1*(4/(2*1+1))
    
            // 4 imposto m=2
            m = 2;
    
            piGrecoPrecedente = nMenoUnoElemento;
            piGreco = nMenoUnoElemento + nElemento;
    
            // finchè |piGreco-piGrecoPrecedente| < epsilon
            while (!(Math.abs(piGreco-piGrecoPrecedente) < epsilon)) {
                piGrecoPrecedente = piGreco;
                // 5.1 il valore del n-1 elemento della successione=
                // il valore del n elemento della successione
                nMenoUnoElemento = nElemento;
                // 5.2 calcolo il nuovo valore del m elemento della successione
                nElemento = Math.pow(-1,m)*(4.0/(2.0*m+1));
                piGreco += nElemento;
                // 5.3 incremento m
                m++;
            }
    
            // 6 stampo il risultato
            return piGreco;
        }
    }
    Attenzione che se testi il programma per n > 7 sono già necessari molti conti (e tempo)...
    SO: Debian Sarge kernel 2.6.11
    Lang: Java, C++, C

  7. #7
    x Lucis

    Grazie per l'aiuto ma ci sono due problemi

    1) il prg non funziona , ovvero mi calcola sempre lo stesso pigreco a prescindere dal numero delle cifre decimali che voglio vedere

    2) ci sono diversi comandi che non conosco....

    ad esempio

    "Math.abs" ???
    "Math.pow" ???
    "return piGreco" ???

    :master:
    E' tutta colpa di Berlusconi !
    Help [Ciclico] Fisco, domande varie

    Avatar

  8. #8
    Ok, evidentemente non hai ancora affrontato i metodi in Java.
    Eccoti una versione del programma senza il metodo:

    codice:
    class PiGreco {
        public static void main(String[] args) {
            // qui viene stabilita la precisione
            int n = 3;
    
            double epsilon,nElemento,nMenoUnoElemento;
            double piGreco,piGrecoPrecedente;
            int m;
            // 2. calcolare epsilon
            // 2.1 inizializzo epsilon = 0.1
            epsilon = 0.1;
            // 2.2 per n volte epsilon=epsilon/10
            for(int i = 0; i < n; i++) {
                epsilon /= 10;
            }
    
            // 3 calcolo il primo e il secondo elemento della serie
            nMenoUnoElemento = 4.0;     // (-1)^0*(4/(2*0+1))
            nElemento = -4.0/3.0;       // (-1)^1*(4/(2*1+1))
    
            // 4 imposto m=2
            m = 2;
    
            piGrecoPrecedente = nMenoUnoElemento;
            piGreco = nMenoUnoElemento + nElemento;
    
            // finchè |piGreco-piGrecoPrecedente| < epsilon
            while (!(Math.abs(piGreco-piGrecoPrecedente) < epsilon)) {
                piGrecoPrecedente = piGreco;
                // 5.1 il valore del n-1 elemento della successione=
                // il valore del n elemento della successione
                nMenoUnoElemento = nElemento;
                // 5.2 calcolo il nuovo valore del m elemento della successione
                nElemento = Math.pow(-1,m)*(4.0/(2.0*m+1));
                piGreco += nElemento;
                // 5.3 incremento m
                m++;
            }
    
            // 6 stampo il risultato
            System.out.println("Il numero cercato è "+piGreco);
        }
    }
    Modificando la precisione si ottengono i seguenti risultati:

    1: 3.1465677471829556
    2: 3.1420924036835256
    3: 3.1416426510898874
    4: 3.141597653564762
    5: 3.1415931535894743
    6: 3.1415927035898146
    7: 3.1415926485894077

    che effettivamente approssimano (secondo la precisione voluta) il vero pigreco (3,1415926535897932384626433832795).

    Programmando in Java incapperai spesso in comandi, metodi, classi, cose varie che non conosci, fortunatamente la documentazione ufficiale spesso risolve:
    http://java.sun.com/j2se/1.4.2/docs/api/index.html.
    In particolare a questo link trovi la documentazione di Math. Come puoi vedere Math.abs(x) restituisce il modulo di x e Math.pow(b,e) restituisce l'elevazione a potenza b^e.
    SO: Debian Sarge kernel 2.6.11
    Lang: Java, C++, C

  9. #9
    x Lucis

    Non so davvero come ringraziarti per l'aiuto che mi stai fornendo!

    Però il prog deve dare un output diverso!

    Col tuo prg l'output è questo :



    Modificando la precisione si ottengono i seguenti risultati:
    1: 3.1465677471829556
    2: 3.1420924036835256
    3: 3.1416426510898874
    4: 3.141597653564762
    5: 3.1415931535894743
    6: 3.1415927035898146
    7: 3.1415926485894077
    mentre l'output richiesto dal prg dev'essere questo :

    Modificando la precisione si ottengono i seguenti risultati:
    1: 3.1
    2: 3.14
    3: 3.141
    4: 3.1415
    5: 3.14159
    6: 3.141592
    7: 3.1415926
    ovvero se imposto la n=1 deve visualizzare un solo decimale,n=2 in output solo 2 decimali..ect..ect..

    Tra l'altro non posso usare nessun commando che mi tronca il numero facendo visualizzare solo n decimali!

    Non posso usare quel commando xchè il prof la considera una soluzione sub-ottimale , ovvero aggira l'ostacolo senza affrontarlo!

    In parole povere io dovrei arrivare a quell'output tramite i conti...ma come???? :master:
    E' tutta colpa di Berlusconi !
    Help [Ciclico] Fisco, domande varie

    Avatar

  10. #10
    A parte il fatto che trattandosi di numeri double al massimo si potrebbe arrivare a qualcosa del tipo

    Modificando la precisione si ottengono i seguenti risultati:
    1: 3.10000000000000
    2: 3.14000000000000
    3: 3.14100000000000
    4: 3.14150000000000
    5: 3.14159000000000
    6: 3.14159200000000
    7: 3.14159260000000
    è un bel problema arrivare a questo output basandosi solo sulla serie in questione. L'unica cosa che mi viene in mente è che potresti moltiplicare il risultato per 10^n, togliere i decimali (magari con cast ad int e poi di nuovo a double) e poi dividere per 10^n, ma è sempre una "sub-soluzione".

    Difficile operare sui termini della sommatoria, dal momento che sono frazioni che generano numeri con infinite cifre decimali...
    SO: Debian Sarge kernel 2.6.11
    Lang: Java, C++, C

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.