– Analisi listato “Calcolo della radice quadrata di un numero intero

Transcript

– Analisi listato “Calcolo della radice quadrata di un numero intero
A. Veneziani – Analisi listato “Calcolo della radice quadrata di un numero intero positivo”
Innanzitutto sono necessari alcuni chiarimenti sull’algoritmo utilizzato per calcolare la radice quadrata di un
numero n che si presuppone intero positivo.
Il procedimento adottato si basa sui seguenti, ripetitivi, passi, validi per tutte le cifre:
a) Individuazione del numero di cifre intere (codice effettuato una sola volta all’inizio)
1. Effettua un ciclo che partendo da 1 calcola la relativa potenza di 10 (10 1 = 10) e si chiede
ogni volta se n sia inferiore alla potenza di 10 stessa. Se al primo passo la potenza (101 =
10) è già maggiore vuol dire che il numero è formato da una sola cifra (cifra delle unità).
2. Se viceversa quanto indicato al punto (a) non accade, allora vuol dire che il numero di cifre
del numero intero è superiore a una. Si aumenta quindi il valore del contatore ncifre di
uno. E questa volta si testa se 102 = 100 è superiore a n.
3. Se ciò accade vuol dire che il numero è formato da due cifre (da 10 fino a 99)
4. Si ripete se del caso le considerazioni ai punti 2 e 3, per ncifre superiore, fino a raggiungere
l’effettivo numero di cifre.
b) Individuato il numero di cifre presenti, si parte dal determinare il valore della cifra più alta della
radice. Nell’ algoritmo utilizzato (per semplicità) il test viene esteso ad un numero di cifre pari al
numero di cifre del numero n 1 .
c) L’algoritmo si basa su due valori chiave:
rad è il valore (approssimato) ormai appurato della radice,
mentre val è il valore, dovuto a cifre successive, che si sta cercando di aggiungere
Entrambi questi valori devono lavorare con buona precisione, quindi sono stati definiti double
(virgola mobile a 64 bit di precisione di calcolo).
Il valore di rad inizialmente è pari a 0, a cui viene poi via via sommato, come incremento
progressivo (sempre più basso), il valore di val.
d) Il test viene effettuato ponendo la cifra in quel momento considerata pari a 1 e poi calcolando il
quadrato del numero così ottenuto; il valore risultante dell’ operazione è posto nella variabile val.
e) Se il quadrato di (rad + val) risulta inferiore a n, allora si aumenta il valore sulla cifra corrente 2, 3, …
ogni volta ripetendo il test, (ossia se il quadrato di (rad + val) risulta inferiore a n).
f) Si continua fino a quando il test da un valore superiore a n, allora la cifra indicata viene fissata alla
cifra precedente all’ultima considerata nel test.
g) La cifra determinata e ormai fissata viene stampata.
h) Se il valore della variabile cifra (vd. nota 2) è pari a 0 (100 = 1), ossia la cifra considerata è quella
delle unità, si inserisce un punto subito dopo aver stampato il valore
i) Si aggiunge la quantità val al valore di rad, determinando una miglior approssimazione della radice.
j) Si passa alla cifra significativa subito successiva ripetendo i punti d -> e 2, fino a raggiungere la
precisione (numero cifre decimali) voluta.
1
In pratica se abbiamo da fare la redice di 100, il programma testa (in modo piuttosto meccanico), per la radice la terza cifra prima della virgola,
ossia quella delle centinaia. In questo caso è ovvio che il valore di tale cifra risulta dover essere 0.
Pagina 1
Dal punto di vista più puramente tecnico il programma si apre con le solite inclusioni a cui si aggiunge
l’inclusione di <math.h> (libreria di funzioni matematiche), in quanto il procedimento utilizza la funzione
potenza ( pow(…,…) ), per calcolare diverse potenze di 10:
#include <iostream>
using namespace std;
#include "math.h"
La parte di codice che effettua quanto indicato al punto (a) (determinazione cifre del numero), viene svolta
dal codice C++:
ncifre = 1;
val = pow(10,ncifre);
while (val < n)
{
ncifre++;
val = pow(10,ncifre);
}
Successivamente individuato in ncifre il numero di cifre, inizia il vero e proprio processo di calcolo della
radice; il procedimento di ripetizione del calcolo delle varie, relativo ai punti (b) ed (i), cifre è implementato
tramite un ciclo for:
rad = 0;
for (cifra = ncifre - 1; cifra >= -7; cifra--)
{
...
in cui la varibile cifra rappresenta la potenza di dieci della cifra considerata, ossia il suo peso in notazione
decimale. Successivamente un altro ciclo determina il valore corretto (0..9) da dare alla singola cifra
considerata. Il codice riportato è quindi quello relativo ai punti (c) -> (f):
num = 1;
val = num * pow(10,cifra);
while (((rad + val) * (rad + val)) <= n)
{
num++;
val = num * pow(10,cifra);
}
num--;
La cifra num viene stampata, e se pari alle unità, viene seguita da un punto, come definito al punto (g)
dell’algoritmo descritto sopra 3:
cout << num;
if (cifra == 0)
cout << ".";
Si incrementa poi, arrivando ad una migliore approssimazione, il valore di rad, come indicato al punto (i),
facendo assumere al valore della cifra trovato (num) il suo peso opportuno (moltiplicazione per la corretta
potenza di 10):
rad = rad + num * pow(10,cifra);
Infine il programma attende la pressione di un tasto e poi termina:
cout << endl;
system("PAUSE");
}
2
L’indicazione su quale cifra stia lavorando l’algoritmo è data dal valore della variabile cifra, che assueme valori pari alla corrispondente potenza di
10.
3
Si potrebbe rifinire l’effetto ottenuto in questa fase impedendo di stampare le cifre 0, non significative, se il valore di cifra è superiore a 1.
Pagina 2