La presentazione è in caricamento. Aspetta per favore

La presentazione è in caricamento. Aspetta per favore

TERNE PITAGORICHE Obiettivi dell’esercitazione

Presentazioni simili


Presentazione sul tema: "TERNE PITAGORICHE Obiettivi dell’esercitazione"— Transcript della presentazione:

1 TERNE PITAGORICHE Obiettivi dell’esercitazione
Realizzare programmi che includano semplici funzioni Contenuti tecnici Scrittura e invocazione di funzioni di calcolo con parametri passati by reference. Uso delle funzioni. Metodo di progetto: Raffinamenti successivi

2 Problema Realizzare un programma che generi e stampi tutte le terne pitagoriche nell'intervallo degli interi (A, B e C formano una terna pitagorica se A2 + B2 = C2). È richiesto che il test venga effettuato da una funzione che restituisca il valore TRUE se la terna passata come parametro è pitagorica, FALSE altrimenti. Suggerimento: attenzione all’overflow della somma!

3 Analisi Occorre provare per tutti gli a, per tutti i b e per tutti i c se (a,b,c) formano una terna pitagorica. Deve essere a2 (e b2 e c2) < INT_MAX, quindi i valori di a, b e c vanno limitati a

4 Schema base val_max = sqrt(INT_MAX); for(a = 1; a <= val_max; a++)
{ for(b = 1; b <= val_max ; b++) for(c = 1; c <= val_max; c++) if(is_terna_pitagorica(a, b, c,)) printf("%d %d %d\n", a, b, c); }

5 Osservazioni Se a, b e c iniziano tutti da 1, verranno trovate le terne equivalenti: 3, 4, 5 4, 3, 5 5, 4,3 Si ovvia iniziando b da un valore successivo ad a, c da un valore successivo a b.

6 val_max = sqrt(INT_MAX);
for(a = 1; a <= val_max; a++) { for(b = a+1; b <= val_max; b++) for(c = b+1; c <= val_max; c++) if(is_terna_pitagorica(a, b, c)) printf("%d %d %d\n", a, b, c); }

7 Se si trova un valore di c che soddisfa alla condizione che a, b, e c sono una terna, è inutile continuare i test con i valori successivi di c! Si usa un flag, trovata_terna, per bloccare il ciclo più interno appena si trova una terna.

8 val_max = sqrt(INT_MAX);
for(a = 1; a <= val_max; a++) { for(b = a+1; b <= val_max; b++) trovata_terna = FALSE; for(c = b+1; (c <= val_max) && !trovata_terna; c++) if(is_terna_pitagorica(a, b, c)) printf("%d %d %d\n", a, b, c); trovata_terna = TRUE; }

9 Funzione is_terna_pitagorica Lo schema
int is_terna_pitagorica(int a, int b, int c) { int risultato; int a_quad_piu_b_quad; a_quad_piu_b_quad = a * a + b * b; risultato = (a_quad_piu_b_quad == c * c); return(risultato); }

10 Osservazione La somma a2 + b2 può dare overflow.
In questo caso il confronto con c2 non ha senso Occorre comunicare al programma chiamante questa condizione (oltre all’informazione se è o meno una terna pitagorica): occorre un parametro passato by-reference Trattandosi di una somma tra valori positivi, il test di overflow si esegue controllando se il risultato è negativo

11 Versione corretta per l’overflow
int is_terna_pitagorica(int a, int b, int c, int *p_stato) { int risultato; int a_quad_piu_b_quad; a_quad_piu_b_quad = a * a + b * b; if(a_quad_piu_b_quad < 0) *p_stato = SI_OVERFLOW; risultato = FALSE; } else *p_stato = NO_OVERFLOW; risultato = (a_quad_piu_b_quad == c * c); return(risultato);

12 Osservazioni per il main
Se per una coppia a, b, si riscontra overflow, è inutile continuare con valori superiori (darebbero overflow a maggior ragione): occorre bloccare i cicli più interni. Il main diventa:

13 Int main() { int val_max; int condizione; int trovata_terna; val_max = sqrt(INT_MAX); for(a = 1; a <= val_max; a++) condizione = NO_OVERFLOW; for(b = a+1; b <= val_max && condizione == NO_OVERFLOW; b++) trovata_terna = FALSE; for(c = b+1; (c <= val_max) && (condizione == NO_OVERFLOW) && !trovata_terna; c++) if(is_terna_pitagorica(a, b, c, &condizione)) printf("%d %d %d\n", a, b, c); trovata_terna = TRUE; } return EXIT_SUCCESS;

14 Problema nella visualizzazione dei risultati
Il numero di terne pitagoriche trovato è molto grande, e il programma le stampa tutte: a causa dello scorrimento dello schermo, si rischia di riuscire a vedere solo quelle finali, perdendo quelle iniziali. Soluzione: bloccare lo schermo ogni 23 righe, chiedendo che venga battuto INVIO per continuare. Il main diventa:

15 #include <stdio.h>
#include <math.h> #include <limits.h> #include <stdlib.h> #define NO_OVERFLOW 0 #define SI_OVERFLOW 1 #define FALSE 0 #define TRUE 1 int is_terna_pitagorica(int a, int b, int c, int *p_stato); Int main() { int a, b, c; int val_max; int condizione; int trovata_terna; int contatore = 0;

16 val_max = sqrt(MAXINT);
for(a = 1; a <= val_max; a++) { condizione = NO_OVERFLOW; for(b = a+1; b <= val_max && condizione == NO_OVERFLOW; b++) trovata_terna = FALSE; for(c = b+1; (c <= val_max) && (condizione == NO_OVERFLOW) && !trovata_terna; c++) if(is_terna_pitagorica(a, b, c, &condizione)) printf("%d %d %d\n", a, b, c); trovata_terna = TRUE; contatore++; if((contatore % 23) == 0) system("PAUSE"); } system(“PAUSE”); return EXIT_SUCCESS;

17 Considerazioni finali
Si è partiti ipotizzando per a, b e c l’intervallo 1  . Si è trovato un vincolo che coinvolge a e b: a2+b2 < INT_MAX (test di overflow). Ad una attenta osservazione, si può vedere che esiste un vincolo tra c e a e b: è inutile testare valori di c per cui c2 > a2+b2. Se ciò accade, possiamo chiudere il ciclo più interno (è stata superata la soglia).

18 Programma definitivo #include <stdio.h> #include <math.h>
#include <limits.h> #include <stdlib.h> #define NO_OVERFLOW 0 #define SI_OVERFLOW 1 #define FALSE 0 #define TRUE 1 int is_terna_pitagorica(int a, int b, int c, int *p_stato, int *p_superato_limite)

19 int main() { int a, b, c; int val_max; int condizione; Int superato_limite; int trovata_terna; int contatore = 0; val_max = sqrt(MAXINT); for(a = 1; a <= val_max; a++) condizione = NO_OVERFLOW; for(b = a+1; b <= val_max && condizione == NO_OVERFLOW; b++)

20 { trovata_terna = FALSE; superato_limite = FALSE; for(c = b+1; (c <= val_max) && (condizione == NO_OVERFLOW) && !trovata_terna && !superato_limite; c++) if(is_terna_pitagorica(a, b, c, &condizione, &superato_limite)) printf("%d %d %d\n", a, b, c); trovata_terna = TRUE; contatore++; if((contatore % 23) == 0) system("PAUSE"); } system(“PAUSE”); return EXIT_SUCCESS;

21 int is_terna_pitagorica(int a, int b, int c, int. p_stato, int
int is_terna_pitagorica(int a, int b, int c, int *p_stato, int *p_superato_limite) { int risultato; int a_quad_piu_b_quad; a_quad_piu_b_quad = a * a + b * b; if(a_quad_piu_b_quad < 0) *p_stato = SI_OVERFLOW; risultato = FALSE; } else *p_stato = NO_OVERFLOW; if(c * c > a_quad_piu_b_quad) *p_superato_limite = TRUE; risultato = (a_quad_piu_b_quad == c * c); return(risultato);


Scaricare ppt "TERNE PITAGORICHE Obiettivi dell’esercitazione"

Presentazioni simili


Annunci Google