Il Massimo Comun Divisore (MCD) è il maggiore intero positivo che divide due numeri senza resto. Se prendete i due termini di una frazione e li dividete per il massimo comun divisore ottenete la frazione semplificata.
Personalmente nel fare conti, anche semplici, ero una vera frana e quindi, appena ho imparato a programmare, ho subito pensato al problema di semplificare le frazioni. Ho quindi inventato il mio primo algoritmo serio proprio per calcolare l'MCD. Peccato che qualche mese dopo io abbia scoperto che un certo Euclide mi aveva preceduto!
Comunque il programma che semplifica una frazione utilizzando un sottoprogramma
per il calcolo dell'MCD per anni è stato molto usato sulle mie
HP 34C e
HP 32S. Era diventato un po' il
mio metro di valutazione della bontà delle calcolatrici. In effetti utilizza
subroutine, loop, istruzioni condizionali, registri di memoria, stack (se esiste)
e semplici funzioni di calcolo. Era un benchmark sulle funzionalità abbastanza
completo. E in effetti nel corso del tempo ho prodotto
implementazioni per altre calcolatrici. Oggi non
ha più molto senso perché quasi tutte le calcolatrici hanno funzioni di calcolo
per le frazioni. Nel frattempo, grazie all'uso assiduo di queste macchinette,
ho anche imparato a fare i conti.
Per la mia HP 34C il programma era più o meno questo (ho scritto alcune varianti nel corso del tempo):
Subroutine A (routine di semplificazione) | Subroutine 9 (routine di calcolo del MCD) |
LBL A |
LBL 9 |
Per usarlo si inserivano i numeratore e denominatore nello stack (catasta nel manuale in italiano) e si premeva il tasto A. Dopo qualche tempo compariva il nuovo numeratore e dopo una pausa il denominatore. Nel registro 2 si trovava il massimo comun divisore.
Comprata la HP 32S l'ho riscritto:
Subroutine S (routine di semplificazione) | Subroutine M (routine di calcolo del MCD) |
LBL S |
LBL M |
Come si può notare il programma è molto simile. In effetti è il motivo fondamentale per cui ho acquistato la HP 32S: un grande livello di compatibilità con la vecchia calcolatrice. In questo caso ho sfruttato le variabili. Si premono i tasti XEQ S e il sistema chiede il numeratore (variabile N) e il denominatore (variabile D). Dopo qualche tempo vengono visualizzati il numeratore e il denominatore semplificati.
Rimanendo nel mondo HP, si può pensare ad una calcolatrice come la HP 50g e a come si può utilizzare il linguaggio RPL per realizzare lo stesso algoritmo. Ho utilizzato la solita struttura: un programma che mostra una semplice interfaccia utente che chiede i due termini della frazione e che semplifica la frazione utilizzando un programma che calcola l'MCD.
Semplifica (programma per la semplificazione) | MCD (programma di calcolo del MCD) |
« |
« |
Ecco come appare il programma:
Si potrebbe ottimizzare ma con la HP 50g questo algoritmo è assolutamente inutile: la calcolatrice esegue calcoli frazionari. E ha incorporata una funzione per calcolare il massimo comun divisore. In effetti va più oltre grazie al CAS incorporato. Se ad esempio scrivete una cosa del tipo:
'(45*(x^2-a))/(15*(x^6-12*x^4+48*x^2
-64)'
'a=4'
SUBST
FACTOR
otterrete
'3/((x+2)^2*(x-2)^2'
Da notare che, nonostante la calcolatrice possa essere usata anche in modo algebrico, io ovviamente uso il modo RPN. Inoltre la calcolatrice utilizza una rappresentazione più vicina a quella che utilizzereste con la carta e quella che ho usato io è la rappresentazione testuale usata internamente dai programmi. Una serie di immagini rendono ancora di più l'idea:
Un bel salto dalla vecchia HP 34C!
Con la HP Prime si utilizza invece il linguaggio HP-PPL, una sorta di linguaggio strutturato che ricorda il BASIC o il PASCAL.
Funzione SEMPLIFICA (interfaccia utente) | Funzione MCD (calcolo del MCD) |
EXPORT SEMPLIFICA() |
// calcola il massimo comun divisore
|
L'interfaccia ricorda molto quella dell'HP 50g:
Nell'HP Prime l'RPN è un mondo abbastanza separato dal CAS e dall'HP-PPL. Quindi per restituire parametri multipli da un programma si può utilizzare una lista, vista la difficoltà di accedere allo stack RPN. In questo caso ho utilizzato la lista predefinita L0 che ho richiamato poi dalla schermata principale della calcolatrice (qui in modalità TextBook).
I vari sistemi CAS permettono di definire funzioni. In questo somigliano a linguaggi funzionali come LISP o F#. E quindi possibile sfruttare queste caratteristiche per scrivere un programma per l'MCD funzionale. Tenendo presente che i loop si sostituiscono con l'uso di funzioni ricorsive e che queste si possono combinare ho definito alcune funzioni per il CAS di HP Prime in grado di effettuare il calcolo dell'MCD:
MCD mediante funzioni ricorsive |
\[ mgcdr(z,w):=z-w*IP(z/w) \] \[ mgcdi(z,w) := \begin{cases} {w \ \mbox{if} \ mgcdr(z,w)=0} \\ {mgcdi(w,mgcdr(z,w)) \ \mbox{if} \ mgcdr(z,w) \neq 0} \end{cases} \] \[ mgcd(a,b):=mgcdi(MAX(|a|,|b|),MIN(|a|,|b|)) \] |
Per usare questo codice basta chiamare la funzione mgcd passando i due valori. Le funzioni possono essere adattate facilmente ad altri CAS. Nel caso dell'HP Prime si può utilizzare anche la sintassi nativa:
MCD per CAS HP Prime mediante funzioni ricorsive |
mgcdr(z,w):=z-w*IP((z/w)) |