Potenza col metodo del contadino russo
Il "metodo del contadino russo" è un procedimento efficiente per il calcolo della potenza a^b
(a
elevato alla potenza di b
).
NOTA: nel seguito, per chiarezza i numeri verranno scritti con notazione anglosassone, ovvero usando il punto per separare i decimali e la virgola per separare le migliaia (es. 1,564,373.03
).
Il metodo consiste nell'avere una variabile risultato
inizializzata pari a 1
.
Dopodichè, si realizza un ciclo nel quale
- la variabile
risultato
viene moltiplicata pera
solo seb
è dispari. - successivamente, si aggiorna il valore di
a
calcolandone il quadrato, mentreb
viene dimezzato, arrotondando per difetto
Il ciclo termina quando b
si annulla.
Esempio
Si supponga di voler calcolare la potenza 3^12
(3
elevato a 12
).
I passi dell'algoritmo determinerebbero la seguente sequenza di valori (risultato
è abbreviato in r
, mentre le "freccette" servono a indicare la valutazione delle espressioni):
r <- 1
a <- 3
b <- 12
r non viene modificato perché b è pari
a = a * a <- 3 * 3 <- 9
b = b / 2 <- 12 / 2 <- 6
r non viene modificato perché b è ancora pari
a = a * a <- 9 * 9 <- 81
b = b / 2 <- 6 / 2 <- 3
r = r * a <- 1 * 81 <- 81 (in questo caso b è dispari)
a = a * a <- 81 * 81 <- 6,561
b = b / 2 <- 3 / 2 <- 1
r = r * a <- 81 * 6,561 <- 531,441 (in questo caso b è dispari)
a = a * a <- 6,561 * 6,561 <- 43,046,721
b = b / 2 <- 1 / 2 <- 0
A questo punto il procedimento termina, in quanto b
si annulla, e il risultato è 531,441
.
NOTA: il risultato è stato ottenuto, in pratica, moltiplicando i due valori 81
e 6561
corrispondenti agli esponenti dispari 3
e 1
.
Richiesta
Si scriva un programma in linguaggio C (chiamiamolo potenza.c
) che legga da terminale la base a
, anche non intera, e l'esponente b
(deve essere intero positivo) e che calcoli la potenza a^b
utilizzando il metodo appena descritto.
La stampa del risultato dovrà essere preceduta da uno specifico marcatore POTENZA
scritto tra parentesi quadre.
Ad esempio, a fronte della sequenza di input 2.5
e 3
il programma dovrà stampare le righe:
[POTENZA]
15.625
Si compili il programma con il comando
gcc -Wall potenza.c
e lo si esegua per verificarne la correttezza.
Verifica automatica
Scarica una versione eseguibile di pvcheck.
I casi di test sono descritti nei file potenza.test. Si verifichi la correttezza del programma scritto precedentemente tramite il comando
./pvcheck -f potenza.test ./a.out
Si corregga il programma finché non fornisce la risposta corretta.
NOTA: l'opzione -f potenza.test
è necessaria in quanto il nome del file differisce da quello predefinito pvcheck.test
. Infatti, se pvcheck
viene invocato come segue
./pvcheck ./a.out
non bisogna specificare l'opzione -f
perché pvcheck
cerca automaticamente un file di test chiamato pvcheck.test
.
Indicazioni per la soluzione
- scrivi la funzione
main
(vedi S2.1) - dichiara le variabili necessarie a contenere i dati del problema (es.,
a
,b
erisultato
) - leggi il valore delle variabili necessarie da tastiera usando
fgets
,atoi
eatof
(ricorda di dichiarare la stringa "di supporto") (vedi S4.1 - utilizza il costrutto iterativo
while
per effettuare il ciclo (vedi S4.7 per la sintassi) - utilizza vari costrutti
if
(vedi S4.3 per la sintassi)
Suggerimenti
- il programma deve considerare il caso in cui l'utente inserisca un valore di
b
negativo, nel qual caso stampi la stringanon calcolabile
nella riga successiva al marcatore - potrebbe servire l'impostazione di condizioni logiche "complesse" nei costrutti condizionali; gli operatori logici necessari sono descritti in S4.5;
- non dimenticare di includere
stdlib.h
per l'uso diatoi
eatof
(e, come già sai, distdio.h
perprintf
efgets
) - dal momento che serve individuare la condizione per cui
b
è dispari, si può usare l'operatore%
oppure il metodo del troncamento della divisione intera (vedi gli esempi in S4.3 e S4.4)
ATTENZIONE: l'espressione a^b
può essere fuorviante:
- anche se viene usata spesso in informatica per indicare l'elevamento a potenza, in C non ha questo significato: non indica l'elevamento a potenza!
- si tratta comunque di una espressione valida in linguaggio C, perché l'operatore
^
viene usato per l'operazione di XOR binario (è illustrato in S11.6.3) - in C non esiste un operatore specifico per l'elevamento a potenza, quindi questa operazione va svolta esplicitamente con dei cicli (come in questo esercizio)
Nella prossima pagina potrai esaminare un esempio di soluzione dell'esercizio.