Il logo di batmath
www.batmath.it

Decimali con periodo massimale

Ogni numero razionale, img, ha una sua rappresentazione decimale (anche se non unica, per esempio img, 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
}

Commenti

Esercizi proposti:

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.

pagina pubblicata il 01/11/2001 - ultimo aggiornamento il 01/09/2003