Che io sappia non ne esistono altri, ma tale argomento fa parte di rami
delle scienze matematiche, che esulano dalle mie competenze.
Per quello che mi riguarda potrei dare un giudizio sull’implementazione
fatta di questo algoritmo e in particolare sul processo di individuazione
del periodo e antiperiodo, ma non essendo stata fornita nessuna implementazione,
propongo la mia scritta in C, che ritengo abbastanza efficiente.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include <math.h>
bool DeterminaPeriodo(char *decimale,char *outPeriodo,char *outAntiPeriodo)
{
int InizioPeriodo;
int LunghezzaPeriodo;
int LunghezzaMassima=strlen(decimale);
char *Periodo=strdup(decimale);
// Ciclo per l'individuazione dell'inizio del periodo
bool PeriodoTrovato=false;
for(InizioPeriodo=0;InizioPeriodo<LunghezzaMassima && !PeriodoTrovato;InizioPeriodo++) {
// Individuazione del periodo
LunghezzaPeriodo=1;
Periodo[0]=decimale[InizioPeriodo];
Periodo[1]=0;
// Ciclo per la lunghezza
while(LunghezzaPeriodo<=LunghezzaMassima-InizioPeriodo-LunghezzaPeriodo) {
// Ciclo per verificare l'esistenza di un periodo
int max=LunghezzaMassima-LunghezzaPeriodo;
int pos=InizioPeriodo+LunghezzaPeriodo;
while(pos<=max && strncmp(Periodo,decimale+pos,LunghezzaPeriodo)==0)
pos+=LunghezzaPeriodo;
if(pos==LunghezzaMassima && LunghezzaPeriodo<LunghezzaMassima) {
PeriodoTrovato=true;
break;
}
else {
Periodo[LunghezzaPeriodo]=decimale[InizioPeriodo+LunghezzaPeriodo];
Periodo[++LunghezzaPeriodo]=0;
}
}
}
if(PeriodoTrovato) {
strcpy(outPeriodo,Periodo);
strncpy(outAntiPeriodo,decimale,InizioPeriodo-1);
outAntiPeriodo[InizioPeriodo-1]=0;
}
free(Periodo);
return PeriodoTrovato;
}
///////////////////////////////////////////////////////////////////////////////
// MAIN
int main(int argc, char *argv[])
{
if(argc!=2)
printf("USO: %s <Numero> ",argv[0]);
else {
char *buffer=argv[1];
printf("Numero = %s ",buffer);
///////////////////////////////////////////////////////////////////////
// Separazione parte decimale e intera
char *punto=strchr(buffer,'.');
if(punto) {
*punto=0;
char *ParteDecimale = punto+1;
char *Periodo = strdup(ParteDecimale);
char *AntiPeriodo = strdup(ParteDecimale);
Periodo[0]=AntiPeriodo[0]=0;
///////////////////////////////////////////////////////////////////
// Determinazione del periodo e antiperiodo
if(DeterminaPeriodo(ParteDecimale,Periodo,AntiPeriodo)==false) {
strcpy(Periodo,"0");
strcpy(AntiPeriodo,ParteDecimale);
}
int m=strlen(Periodo);
int n=strlen(AntiPeriodo);
printf("Periodo = %s "
"Antiperiodo = %s ",
Periodo, AntiPeriodo);
free(Periodo);
free(AntiPeriodo);
///////////////////////////////////////////////////////////////////
// Calcolo della frazione
*punto='.';
double Valore = atof(buffer);
double Denominatore = pow(10,n+m)-pow(10,n);
double Numeratore = Valore*Denominatore;
printf("Frazione = %0.0f/%0.0f ",Numeratore,Denominatore);
}
else
printf("Frazione = %s/1 ",buffer);
}
return 0;
}
Il programma accetta un parametro da riga di comando che sarà un numero
espresso gia sottoforma di vettore di caratteri.
L’individuazione di un periodo è un’elaborazione di una stringa, che alla
fine non risulta neanche troppo pesante dal punto di vista computazionale,
richiedendo delle semplici comparazioni tra sottostringhe di quella data.
I commenti nel codice dovrebbero essere sufficienti, per cui mi dilungo
in noiose spiegazioni.
Invece potrebbero essere più interessanti i seguenti siti.
Link:
Matematica
Discreta
Una
spiegazione semplificata
Risorse
matematiche