Ogni numero razionale, , ha una sua
rappresentazione decimale (anche se non unica, per esempio
, ma qui tralasciamo il caso del periodo 9
che non può uscire da una divisione). Come è noto
una tal rappresentazione decimale è sempre finita o
periodica (si potrebbe dire periodica se conveniamo che i
decimali finiti abbiano periodo zero) e il massimo numero di
cifre dopo la virgola, se ci limitiamo al primo periodo,
è uno meno del denominatore. Questo risultato è
immediato: se infatti eseguiamo la divisione tra n e
d, otteniamo dei resti e la divisione può
cessare quando uno dei resti si ripete o diventa zero.
Poiché i resti non possono superare d è
chiaro che dopo al più d passi uno dei resti
deve ripetersi. Nel caso in cui il periodo abbia esattamente
d-1 cifre (cioè il massimo possibile), il
decimale si dice periodico massimale. In questo
programma vogliamo ricercare i periodici massimali tra i
reciproci dei naturali.
L'algoritmo è estremamente semplice: abbiamo introdotto un array dove inseriamo successivamente i resti della divisione. Ogni volta che si trova un resto lo si confronta con tutti i precedenti: la divisione termina se c'é una ripetizione. Per includere il caso del resto zero (decimali finiti) abbiamo posto uguale a zero il primo elemento dell'array: in questo modo la divisione termina non appena un resto è zero. In considerazione del particolare caso che vogliamo considerare (reciproci dei naturali) il primo resto è sempre uno, ed abbiamo posto uguale ad uno il secondo elemento dell'array. Tutto il resto dell'algoritmo serve a presentare, in modo gradevole, i risultati. Per questo abbiamo introdotto un secondo array dove inseriamo successivamente le cifre del quoziente (array che inizia, necessariamente, con "0,"). Per scrivere i risultati abbiamo usato il meccanismo della sostituzione dinamica dell'HTML, usando la proprietà innerHTML di un elemento <SPAN> del codice. Come al solito per richiamare l'elemento in oggetto abbiamo dovuto dargli un nome la cosa questa volta si fa con un attributo ID del tag, anziché con il name, come si fa nel caso, per esempio, degli elementi di un <FORM>. Il codice contiene una serie di commenti che lo rendono facilmente comprensibile. Nel codice che segue abbiamo messo in grassetto l'algoritmo vero e proprio.
function massimale()
{
document.getElementById('primomessaggio').innerHTML="
"
//Cancella eventuali messaggi rimasti nello
<span id="primomessaggio">
document.getElementById('secondomessaggio').innerHTML="
"
//Cancella eventuali messaggi rimasti nello
<span id="secondomessaggio">
document.getElementById('terzomessaggio').innerHTML="
"
//Cancella eventuali messaggi rimasti nello
<span id="terzomessaggio">
document.getElementById('out').innerHTML="
"
//Cancella eventuali messaggi rimasti nello
<span id="outmessaggio">
var den =
parseInt(document.getElementById('denominatore').value);
//E' il denominatore introdotto
dall'utente
if (isNaN(den) || den<2)
{
document.getElementById('primomessaggio').innerHTML="
Non imbrogliare, introduci un intero maggiore di
1!!!";
}
else {
var resti = new Array();
//Array dove piazziamo i successivi resti
della divisione
resti[0]=0;
/*Il primo resto è definito zero
perché serve nel confronto dell'if interno al
while
in quanto se un resto è zero, allora la divisione
si arresta e il decimale è finito */
resti[1]=1;
//il secondo resto è definito 1
perché va bene per tutte le frazioni in questione
var quozienti = new Array();
//Array dove piazziamo le successive cifre
della divisione
var a=true;
//Variabile boolena per il ciclo while che
segue
var i=2;
//Variabile contatore per il ciclo while che
segue
var inizio=0;
//Variabile che memorizza dove inizia il
periodo - se il valore rimane 0, il numero decimale è
finito
var sviluppo="0,";
/*Variabile che memorizza, in forma di
stringa, lo sviluppo decimale.
Lo sviluppo inizia ovviamente sempre con "0,"
.
La stringa non è ancora formattata.*/
while(a)
{
resti[i]=resti[i-1]*10%den;
quozienti[i]=parseInt(resti[i-1]*10/den);
sviluppo=sviluppo+quozienti[i];
for (j=0;j<i;j++)
{
if (resti[i]==resti[j])
{
a=false;
inizio=j;
}
}
i++;
}
var lunghezza = quozienti.length-inizio-1;
//variabile che memorizza la lunghezza del
periodo
var den1=den-1;
//la parte di codice che segue formatta la
stringa "sviluppo" in modo da evidenziare il periodo,
se c'è
subsviluppo1=sviluppo.substring(0,inizio+1);
subsviluppo2=sviluppo.substring(inizio+1,sviluppo.length+1);
//fine della parte di codice che formatta la
stringa "sviluppo"
if (inizio==0)
document.getElementById('out').innerHTML=sviluppo;
else
document.getElementById('out').innerHTML=subsviluppo1+"(<span
class='arancio'>"+subsviluppo2+"</span>)";
if (inizio == 0)
{
document.getElementById('primomessaggio').innerHTML="<span
class='arancio'>Il denominatore da te
introdotto, "+den+", è tale che la frazione
1/"+den+" ha il seguente sviluppo decimale:
</span>"
document.getElementById('secondomessaggio').innerHTML="
Il numero è un decimale finito.";
}
if (inizio == 1)
{
document.getElementById('primomessaggio').innerHTML="<span
class='arancio'>Il denominatore da te
introdotto, "+den+", è tale che la frazione
1/"+den+" ha il seguente sviluppo decimale, limitato
al primo periodo: </span>"
document.getElementById('secondomessaggio').innerHTML="
Il numero è un decimale periodico
semplice";
document.getElementById('terzomessaggio').innerHTML="
, con periodo composto da "+lunghezza+"
cifre.";
}
if (inizio > 1)
{
document.getElementById('primomessaggio').innerHTML="<span
class='arancio'>Il denominatore da te
introdotto, "+den+", è tale che la frazione
1/"+den+" ha il seguente sviluppo decimale, limitato
al primo periodo: </span>"
document.getElementById('secondomessaggio').innerHTML="
Il numero è un decimale periodico
misto";
document.getElementById('terzomessaggio').innerHTML="
, con periodo composto da "+lunghezza+"
cifra(cifre).";
}
if ((i-2==den-1) && (resti[i-1]==1))
{
document.getElementById('primomessaggio').innerHTML="<span
class='arancio'>Il denominatore da te
introdotto, "+den+", è tale che la frazione
1/"+den+" ha il seguente sviluppo decimale, limitato
al primo periodo: </span>"
document.getElementById('terzomessaggio').innerHTML="
, con periodo massimale, cioè composto da
"+den1+" cifre."
}
document.getElementById('messaggiodichiusura').innerHTML="
<em>Se vuoi provare con altri numeri basta inserirli nella
casella di input. Per uscire chiudi la
finestra</em>";
} //chiusura dell'else
}
Questo programma è la traduzione in javascript di un programma scritto in Turbo Pascal per Windows una decina d'anni fa. Per chi ha ancora questo compilatore, o semplicemente per chi vuole fare un confronto tra i due stili di programmazione, forniamo il sorgente di questo programma in Turbo Pascal. Come ora, anche in quel caso si trattava di un programma ad esclusivo scopo didattico, per cui sicuramente l'implementazione non era la più efficiente possibile.